Compare commits

..

3 Commits
1.0.6 ... 0.1.5

Author SHA1 Message Date
Kevin P. Fleming
da55b7728d remove extraneous svn:executable properties
git-svn-id: https://origsvn.digium.com/svn/asterisk/tags/0.1.5@7221 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2005-11-29 18:24:39 +00:00
Kevin P. Fleming
f6ee4f240a automatic tag renames
git-svn-id: https://origsvn.digium.com/svn/asterisk/tags/0.1.5@7201 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2005-11-27 17:18:34 +00:00
Admin Commit
e3bf663a8d This commit was manufactured by cvs2svn to create tag 'v0-1-5'.
git-svn-id: https://origsvn.digium.com/svn/asterisk/tags/v0-1-5@223 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2000-12-14 13:50:41 +00:00
965 changed files with 21856 additions and 203693 deletions

30
BUGS
View File

@@ -1,23 +1,11 @@
Asterisk 1.0-RC-1 Known Major Bugs
==================================
* Some people still have issues with H.323
* QuickNet driver still not entirely stable
* EVERYTHING MARKED WITH "XXX" IN THE SOURCE REPRESENTS A BUG! Sometimes
these bugs are in asterisk, and sometimes they relate to the products
that asterisk uses.
Asterisk Bug Tracking Information
=================================
* The translator API may introduce warble in the case of going in both
directions, but I haven't verified that. The trouble should only enter
in the case of mismatched frame lengths.
To learn about and report Asterisk bugs or make feature
requests, please visit the official Asterisk Bug Tracker
at:
http://bugs.digium.com
For more information on using the bug tracker, or to
learn how you can contribute by acting as a bug marshal
please see:
http://www.digium.com/bugtracker.html
Thank you!
Mark
* In general Asterisk is a very new program, and there are liable to be
many bugs yet to be discovered, so if you think you've found one, please
be sure to report it.

458
CHANGES
View File

@@ -1,461 +1,3 @@
NOTE: Corrections or additions to the ChangeLog may be submitted
to http://bugs.digium.com. Documentation and formatting
fixes are not listed here. A complete listing of changes
is available through the Asterisk-CVS mailing list hosted
at http://lists.digium.com.
Asterisk 1.0.6
-- chan_iax2:
-- Fixed a bug dealing with a division by zero that could cause a crash
-- chan_sip:
-- Behavior was changed so that when a registration fails due to DNS resolution issues,
a retry will be attempted in 20 seconds.
-- Peer settings were not reset to null values when reloading the configuration file.
Behavior has been changed so that these values are now cleared.
-- 'restrictcid' now properly works on MySQL peers.
-- Only use the default callerid if it has been specified.
-- Asterisk was not sending the same From: line in SIP messages during certain times.
Fixed to make sure it stays the same. This makes some providers happier, to a working state.
-- Certain circumstances involving a blank callerid caused asterisk to segmentation fault.
-- There was a problem incorrectly matching codec availablity when global preferences were
different from that of the user. To fix this, processing of SDP data has been moved
to after determining who the call is coming from.
-- Asterisk would run out of RTP ports while waiting for SUBSCRIBE's to expire even though
an RTP port isn't needed in this case. This has been fixed by releasing the ports early.
-- chan_zap:
-- During a certain scenario when using flash and '#' transfers you would hear the
other person and the music they were hearing. This has been fixed.
-- A fix for a compilation issue with gcc4 was added.
-- chan_modem_bestdata:
-- A fix for a compilation issue with gcc4 was added.
-- format_g729:
-- Treat a 10-byte read as an end of file indication instead of an error. Some G729 encoders
like to put 10-bytes at the end to indicate this.
-- res_features:
-- During certain situations when parking a call, both endpoints would get musiconhold.
This has been fixed so the individual who parked the call will hear the digits and not
musiconhold.
-- app_dial:
-- DIALEDPEERNUMBER is now being set, so if you attempted to use it in the past and failed
it should work now.
-- A callerid change caused many headaches, this has been reversed to the original 1.0 behavior.
-- A crash caused with the combination of the 'g' option and # transfer was fixed.
-- app_voicemail:
-- If two people hit the voicemail system at the same time, and were leaving a message
the second message was overwriting the first. This has been fixed so that each one
is distinct and will not overwrite eachother.
-- cdr_tds:
-- If the server you were using was going down, it had the potential to bring your asterisk
server down with it. Extra stuff has been added so as to bring in more error/connection
checking.
-- cdr_pgsql:
-- This will now attempt to reconnect after a connection problem.
-- IAXY firmware:
-- This has been updated to version 23. It includes a fix for lost registrations.
-- internals
-- Behavior was changed for 'show codec <number>' to make it more intuitive. (kshumard)
-- DNS failures and asterisk do not get along too well, this is not totally the case anymore.
-- Asterisk will now handle DNS failures at startup more gracefully, and won't crash and
burn.
-- Choosing to append to a wave file would render the outputted wave file corrupt. Appending
now works again.
-- If you failed to define certain keys, asterisk had the potential to crash when seeing if you had
used them.
-- Attempting to use such things as ${EXTEN:-1} gave a wrong return value. However, this was never
a documented feature...
Asterisk 1.0.5
-- chan_zap
-- fix a callerid bug introduced in 1.0.4
-- app_queue
-- fix some penalty behavior
Asterisk 1.0.4
-- general
-- fix memory leak evident with extensive use of variables
-- update IAXy firmware to version 22
-- enable some special write protection
-- enable outbound DTMF
-- fix seg fault with incorrect usage of SetVar
-- other minor fixes including typos and doc updates
-- chan_sip
-- fix codecs to not be case sensitive
-- Re-use auth credentials
-- fix MWI when using type=friend
-- fix global NAT option
-- chan_agent / chan_local
-- fix incorrect use count
-- chan_zap
-- Allow CID rings to be configured in zapata.conf
-- no more patching needed for UK CID
-- app_macro
-- allow Macros to exit with '*' or '#' like regular extension processing
-- app_voicemail
-- don't allow '#' as a password
-- add option to save voicemail before going to the operator
-- fix global operator=yes
-- app_read
-- return 0 instead of -1 if user enters nothing
-- res_agi
-- don't exit AGI when file not found to stream
-- send script parameter when using FastAGI
Asterisk 1.0.3
-- chan_zap
-- fix seg fault when doing *0 to flash a trunk
-- rtp
-- seg fault fix
-- chan_sip
-- fix to prevent seg fault when attempting a transfer
-- fix bug with supervised transfers
-- fix codec preferences
-- chan_h323
-- fix compilation problem
-- chan_iax2
-- avoid a deadlock related to a static config of a BUNCH of peers
-- cdr_pgsql
-- fix memory leak when reading config
-- Numerous other minor bug fixes
Asterisk 1.0.2
-- Major bugfix release
Asterisk 1.0.1
-- Added AGI over TCP support
-- Add ability to purge callers from queue if no agents are logged in
-- Fix inband PRI indication detection
-- Fix for MGCP - always request digits if no RTP stream
-- Fixed seg fault for ast_control_streamfile
-- Make pick-up extension configurable via features.conf
-- Numerous other bug fixes
Asterisk 1.0.0
-- Use Q.931 standard cause codes for asterisk cause codes
-- Bug fixes from the bug tracker
Asterisk 1.0-RC2
-- Additional CDR backends
-- Allow muted to reconnect
-- Call parking improvements (including SIP parking support)
-- Added licensed hold music from FreePlayMusic
-- GR-303 and Zap improvements
-- More bug fixes from the bug tracker
-- Improved FreeBSD/OpenBSD/MacOS X support
Asterisk 1.0-RC1
-- Innumerable bug fixes and features from the bug tracker
-- Added Open Settlement Protocol (OSP) support
-- Added Non-facility Associated Signalling (NFAS) Support
-- Added alarm Monitoring support
-- Added new MeetMe options
-- Added GR-303 Support
-- Added trunk groups
-- ADPCM Standardization
-- Numerous bug fixes
-- Add IAX2 Firmware Support
-- Add G.726 support
-- Add ices/icecast support
-- Numerous bug fixes
Asterisk 0.7.2
-- Countless small bug fixes from bug tracker
-- DSP Fixes
-- Fix unloading of Zaptel
-- Pass Caller*ID/ANI properly on call forwarding
-- Add indication for Italy
Asterisk 0.7.1
-- Fixed timed include context's and GotoIfTime
-- Fixed chan_h323 it now gets remote ip properly instead of 127.0.0.1
Asterisk 0.7.0
-- Removed MP3 format and codec
-- Can now load and unload SIP,IAX,IAX2,H323 channels without core
-- Fixed various compiler warnings and clean up source tree
-- Preliminary AES Support
-- Fix SIP REINVITE
-- Outbound SIP registration behind NAT using externip
-- More CLI documentation and clean up
-- Pin numbers on MeeMe
-- Dynamic MeetMe conferences are more consistent with static conferences
-- Added channel variables ${HANGUPCAUSE}, ${SIPDOMAIN}, ${TIMESTAMP}, ${ACCONTCODE}
-- ODBC support for logging CDRs
-- Indications for Norway and New Zeland
-- Major redesign of app_voicemail
-- Syslog support
-- Reload logfiles with CLI command 'logger reload' and rotate logs with "logger rotate'
-- Configurable DEBUG, NOTICE, WARNING, ERROR and ast_verbose messages now appear on remote console
-- Properly reaping any zombie processes
-- Added applications SayUnixTime, SetCDRUserField, HasNewVoicemail, ZapScan, Random, ResetCDR, NoCDR
-- Make PRI Hangup Cause available to the dialplan
-- Verify included contexts in extensions.conf
-- Add DESTDIR support for building RPMs and packages
-- Do route lookups on OpenBSD
-- Add support for building on FreeBSD and OS X
-- Add support for PostgreSQL in Voicemail
-- Translate SIP hangup cause to PRI hangup cause where needed
-- Better support for MOH in IAX2
-- Fix SIP problem where channels were not removed on BYE
-- Display codecs by name
-- Remove MySQL and put PGSql instead for licensing reasons
-- Better capability matching in SIP
-- Full IBR4 compliance for chan_zap
-- More flexible CDR handling
-- Distinguish between BUSY and FAILURE on outbound calls
-- Add initial support for SCCP via chan_skinny
-- Better support for Future Group B signaling
Asterisk 0.5.0
-- Retain IAX2 and SIP registrations past shutdown/crash and restart
-- True data mode bridging when possible
-- H.323 build improvements
-- Agent Callback-login support
-- RFC2833 Improvements
-- Add thread debugging
-- Add optional pedantic SIP checking for Pingtel
-- Allow extension names, include context, switch to use global vars.
-- Allow variables in extensions.conf to reference previously defined ones
-- Merge voicemail enhancements (app_voicemail2)
-- Add multiple queueing strategies
-- Merge support for 'T'
-- Allow pending agent calling (Agent/:1)
-- Add groupings to agents.conf
-- Add video support to IAX2
-- Zaptel optimize playback
-- Add video support to SIP
-- Make RTP ports configurable
-- Add RDNIS support to SIP and IAX2
-- Add transfer app (implement in SIP and IAX2)
-- Make voicemail segmentable by context (app_voicemail2)
-- Major restructuring of voicemail (app_voicemail2)
-- Add initial ENUM support
-- Add malloc debugging support
-- Add preliminary Voicetronix support
-- Add iLBC codec
Asterisk 0.4.0
-- Merge and edit Nick's FXO dial support
-- Reengineer SIP registration (outbound)
-- Support call pickup on SIP and compatibly with ZAP
-- Support 302 Redirect on SIP
-- Management interface improvements
-- Add "hint" support
-- Improve call forwarding using new "Local" channel driver.
-- Add "Local" channel
-- Substantial SIP enhancements including retransmissions
-- Enforce case sensitivity on extension/context names
-- Add monitor support (Thanks, Mahmut)
-- Add experimental "trunk" option to IAX2 for high density VoIP
-- Add experimental "debug channel" command
-- Add 'C' flag to dial command to reset call detail record (handy for calling cards)
-- Add NAT and dynamic support to MGCP
-- Allow selection of in-band, out-of-band, or INFO based DTMF
-- Add contributed "*80" support to blacklist numbers (Thanks James!)
-- Add "NAT" option to sip user, peer, friend
-- Add experimental "IAX2" protocol
-- Change special variable "EXTEN-n" to "EXTEN:n" to follow Bash syntax
-- Add "Enhanced" AGI with audio pass-through (voice recognition anyone?)
-- Choose best priority from codec from allow/disallow
-- Reject SIP calls to self
-- Allow SIP registration to provide an alternative contact
-- Make HOLD on SIP make use of asterisk MOH
-- Add supervised transfer (tested with Pingtel only)
-- Allow maxexpirey and defaultexpirey to be runtime configurable for SIP
-- Preliminary codec 13 support (RFC3389)
-- Add app_authenticate for general purpose authentication
-- Optimize RTP and smoother
-- Create special variable "EXTEN-n" where it is extension stripped by n MSD
-- Fix uninitialized frame pointer in channel.c
-- Add global variables support under [globals] of extensions.conf
-- Add macro support (show application Macro)
-- Allow [123-5] etc in extensions
-- Allow format of App(arg1,arg2,...) instead of just App,arg1|arg2 in dialplan
-- Add message waiting indicator to SIP
-- Fix double free bug in channel.c
Asterisk 0.3.0
-- Add fastfoward, rewind, seek, and truncate functions to streams
-- Support registration
-- Add G729 format
-- Permit applications to return a digit indicating new extension
-- Change "SHUTDOWN" to "STOP" in commands
-- SIP "Hold" fixes and VXML URI support
-- New chan_zap with 160 sample chunk size
-- Add DTMF, MF, and Fax tone detector to dsp routines
-- Allow overlap dialing (inbound) on PRI
-- Enable tone detection with PRI
-- Add special information tone detection
-- Add Asterisk DB support
-- Add pulse dialing
-- Re-record all system prompts
-- Change "timelen" to samples for better accuracy
-- Move to editline, eliminating readline dependency
-- Add peer "poke" support to SIP and IAX
-- Add experimental call progress detection
-- Add SIP authentication (digest)
-- Add RDNIS
-- Reroute faxes to "fax" extension
-- Create ISDN/modem group concept
-- Centralize indication
-- Add initial MGCP support
-- SIP debugging cleanup
-- SIP reload
-- SIP commands (show channels, etc)
-- Add optional busy detection
-- Add Visual Message Waiting Indicator (MDMF and SDMF)
-- Add ambiguous extension matching
-- Add *69
-- Major SIP enhancements from SIPit
-- Rewrite of ZAP CLASS features using subchannels
-- Enhanced call parking
-- Add extended outgoing spool support (pbx_spool)
Asterisk 0.2.0
-- Outbound origination API
-- Call management improvements
-- Add Do Not Disturb (*78, *79)
-- Add agents
-- Document variables
-- Add transfer capability on the console
-- Add SpeeX codec translator
-- Add call queues
-- Add setcallerid functionality (AGI, application)
-- Add special variables ${CALLERID}, ${EXTEN}, ${CONTEXT}, ${PRIORITY}
-- Don't echo cancel on pure TDM connections by default
-- Implement Async GOTO
-- Differentiate softhangups
-- Add date/time
Asterisk 0.1.12
-- Fix for Big Endian machines
-- MySQL CDR Engine
-- Various SIP fixes and enhancements
-- Add "zapateller application and arbitrary tone pairs
-- Don't always start at "s"
-- Separate linear mode for pseudo and real
-- Add initial RTP and SIP support (no jitter buffer yet, unknown stability)
-- Add 'h' extension, executed on hangup
-- Add duration timer to message info
-- Add web based voicemail checking ("make webvmail")
-- Add ast_queue_frame function and eliminate frame pipes in most drivers
-- Centralize host access (and possibly future ACL's)
-- Add Caller*ID on PhoneJack (Thanks Nathan)
-- Add "safe_asterisk" wrapper script to auto-restart Asterisk
-- Indicate ringback on chan_phone
-- Add answer confirmation (press '#' to confirm answer)
-- Add distinctive ring support (e.g. Dial,Zap/4r2)
-- Add ANSI/vt100 color support
-- Make parking configurable through parking.conf
-- Fix the empty voicemail problem
-- Add Music On Hold
-- Add ADSI Compiler (app_adsiprog)
-- Extensive DISA re-work to improve tone generation
-- Reset all idle channels every 10 minutes on a PRI
-- Reset channels which are hungup with "channel in use"
-- Implement VNAK support in chan_iax
-- Fix chan_oss to support proper hangups and autoanswer
-- Make shutdown properly hangup channels
-- Add idling capability to chan_zap for idle-net
-- Add "MeetMe" conferencing app (app_meetme)
-- Add timing information to include
Asterisk 0.1.11
-- Add ISDN RAS capability
-- Add stutter dialtone to Chan Zap
-- Add "#include" capability to config files.
-- Add call-forward variable to Chan Zap (*72, *73)
-- Optimize IAX flow when transfer isn't possible
-- Allow transmission of ANI over IAX
Asterisk 0.1.10
-- Make ast_readstring parameter be the max # of digits, not the max size with \0
-- Make up any missing messages on the fly
-- Add support for specific DTMF interruption to saying numbers
-- Add new "u" and "b" options to condense busy/unavail handling
-- Add support for RSA authentication on IAX calls
-- Add support for ADSI compatible CPE
-- Outgoing call queue
-- Remote dialplan fixes for Quicknet
-- Added AGI commands supporting TDD functions (RECEIVE CHAR & TDD MODE)
-- Added TDD support (send/receive text in chan_zap)
-- Fix all strncpy references
-- Implement CSV CDR backend
-- Implement Call Detail Records
Asterisk 0.1.9
-- Implement IAX quelching
-- Allow Caller*ID to be overridden and suggested
-- Configure defaults to use IAXTEL
-- Allow remote dialplan polling via IAX
-- Eliminate ast_longest_extension
-- Implement dialplan request/reply
-- Let peers have allow/disallow for codecs
-- Change allow/deny to permit/deny in IAX
-- Allow dialplan entries to match Caller*ID as well
-- Added AGI (Asterisk Gateway Interface) scripting interface (app_agi)
-- Added chan_zap for zapata telephony kernel interface, removed chan_tor
-- Add convenience functions
-- Fix race condition in channel hangup
-- Fix memory leaks in both asterisk and iax frame allocations
-- Add "iax show stats" command and -DTRACE_FRAMES (for frame tracing)
-- Add DISA application (Thanks to Jim Dixon)
-- Add IAX transfer support
-- Add URL and HTML transmission
-- Add application for sending images
-- Add RedHat RPM spec file and build capability
-- Fix GSM WAV file format bug
-- Move ignorepat to main dialplan
-- Add ability to specificy TOS bits in IAX
-- Allow username:password in IAX strings
-- Updates to PhoneJack interface
-- Allow "servermail" in voicemail.conf to override e-mail in "from" line
-- Add 'skip' option to app_playback
-- Reject IAX calls on unknown extensions
-- Fix version stuff
Asterisk 0.1.8
-- Keep track of version information
-- Add -f to cause Asterisk not to fork
-- Keep important information in voicemail .txt file
-- Adtran Voice over Frame Relay updates
-- Implement option setting/querying of channel drivers
-- IAX performance improvements and protocol fixes
-- Substantial enhancement of console channel driver
-- Add IAX registration. Now IAX can dynamically register
-- Add flash-hook transfer on tormenta channels
-- Added Three Way Calling on tormenta channels
-- Start on concept of zombie channel
-- Add Call Waiting CallerID
-- Keep track of who registeres contexts, includes, and extensions
-- Added Call Waiting(tm), *67, *70, and *82 codes
-- Move parked calls into "parkedcalls" context by default
-- Allow dialplan to be displayed
-- Allow "=>" instead of just "=" to make instantiation clearer
-- Asterisk forks if called with no arguments
-- Add remote control by running asterisk -vvvc
-- Adjust verboseness with "set verbose" now
-- No longer requires libaudiofile
-- Install beep
-- Make PBX Config module reload extensions on SIGHUP
-- Allow modules to be reloaded when SIGHUP is received
-- Variables now contain line numbers
-- Make dialer send in band signalling
-- Add record application
-- Added PRI signalling to Tormenta driver
-- Allow use of BYEXTENSION in "Goto"
-- Allow adjustment of gains on tormenta channels
-- Added raw PCM file format support
-- Add U-law translator
-- Fix DTMF handling in bridge code
-- Fix access control with IAX
* Asterisk 0.1.7
-- Update configuration files and add some missing sounds
-- Added ability to include one context in another
-- Rewrite of PBX switching
-- Major mods to dialler application
-- Added Caller*ID spill reception
-- Added Dialogic VOX file format support
-- Added ADPCM Codec
-- Add Tormenta driver (RBS signalling)
-- Add Caller*ID spill creation
-- Rewrite of translation layer entirely
-- Add ability to run PBX without additional thread
* Asterisk 0.1.6
-- Make app_dial handle a lack of translators smoothly
-- Add ISDN4Linux support -- dtmf is weird...
-- Minor bug fixes
* Asterisk 0.1.5
-- Fix a small mistake in IAX
-- Fix the QuickNet driver to work with newer cards

71
CREDITS
View File

@@ -1,71 +1,10 @@
=== DEVELOPMENT SUPPORT ===
I'd like to thank the following companies for helping fund development of
Asterisk:
Pilosoft, Inc. - for supporting ADSI development in Asterisk
Asterlink, Inc. - for supporting broad Asterisk development
GFS - for supporting ALSA development
Telesthetic - for supporting SIP development
Christos Ricudis - for substantial code contributions
Paul Bagyenda, Digital Solutions - for initial Voicetronix driver development
=== WISHLIST CONTRIBUTERS ===
Jeremy McNamara - SpeeX support
Nick Seraphin - RDNIS support
Gary - Phonejack ADSI (in progress)
Wasim - Hangup detect
=== HARDWARE DONORS ===
* Special thanks to Adtran, Inc, for their donation of an Adtran Atlas,
and TSU 120e to the project. (http://www.adtran.com)
* Thanks to QuickNet Technologies for their donation of an Internet
PhoneJack and Linejack card to the project. (http://www.quicknet.net)
=== MISCELLANEOUS PATCHES ===
Anthony Minessale - Countless big and small fixes, and relentless forward push
anthmct@yahoo.com http://www.asterlink.com
James Golovich - Innumerable contributions
You can find him and asterisk-perl at http://asterisk.gnuinter.net
Andre Bierwirth - Extension hints and status
Oliver Daudey - ISDN4Linux fixes
Pauline Middelink - ISDN4Linux patches and some general patches.
She can be found at http://www.polyware.nl/~middelink/En/
Jean-Denis Girard - Various contributions from the South Pacific Islands
jd-girard@esoft.pf http://www.esoft.pf
William Jordan / Vonage - MySQL enhancmenets to Voicemail
wjordan@vonage.com
Jac Kersing - Various fixes
Steven Critchfield - Seek and Trunc functions for playback and recording
critch@basesys.com
Jefferson Noxon - app_lookupcidname, app_db, and various other contributions
Klaus-Peter Junghanns - in-band DTMF on SIP and MGCP
Ross Finlayson - Dynamic RTP payload support
Mahmut Fettahlioglu - Audio recording, music-on-hold changes, alaw file
format, and various fixes. Can be contacted at mahmut@oa.com.au
James Dennis - Cisco SIP compatibility patches to work with SIP service
providers. Can be contacted at asterisk@jdennis.net
Tilghman Lesher - - Route lookup code; ast_localtime(), ast_say_date_with_format();
GotoIfTime, Random, SayUnixTime, HasNewVoicemail, and Cut applications,
along with various other patches. http://asterisk.drunkcoder.com/
Jayson Vantuyl - Manager protocol changes, various other bugs.
jvantuyl@computingedge.net
Thorsten Lockert - OpenBSD, FreeBSD ports, making MacOS X port run on 10.3,
dialplan include verification, route lookup on OpenBSD, various other
bugs. tholo@sigmasoft.com
Brian West - ODBC support and Bug Marshaling
William Waites - syslog support, SIP NAT traversal for SIP-UA. ww@styx.org
Rich Murphey - Porting to FreeBSD, NetBSD, OpenBSD, and Darwin.
rich@whiteoaklabs.com http://whiteoaklabs.com
=== OTHER CONTRIBUTIONS ===
John Todd - Monkey sounds and associated teletorture prompt
=== HOLD MUSIC ===
Music provided by www.opsound.org
PhoneJack card to the project. (http://www.quicknet.net)
=== OTHER SOURCE CODE IN ASTERISK ===

View File

@@ -1,70 +0,0 @@
A PBX is only really useful if you can get calls into it. Of course, you
can use Asterisk with VoIP calls (SIP, H.323, IAX), but you can also talk
to the real PSTN through various cards.
Supported Hardware is divided into two general groups: Zaptel devices and
non-zaptel devices. The Zaptel compatible hardware supports pseudo-TDM
conferencing and all call features through chan_zap, whereas non-zaptel
compatible hardware may have different features.
Zaptel compatible hardware
==========================
-- Digium (Primary author of Asterisk)
http://www.digium.com, http://store.yahoo.com/asteriskpbx
* Wildcard X100P - Single FXO interface connects to Loopstart phone
line
* Wildcard T400P (obsolete) - Quad T1 interface connects to four T1/PRI
interfaces. Supports RBS and PRI voice and PPP, FR, and HDLC data.
* Wildcard E400P (obsolete)- Quad E1 interface connects to four E1/PRI
(or PRA) interfaces. Supports PRA/PRI, EuroISDN voice and data.
* Wildcard T100P - Single T1 interface connects to a single T1/PRI
interface. Supports RBS and PRI voice and PPP, FR, and HDLC data.
* Wildcard E100P - Single E1 interface connects to a single E1/PRI (or PRA)
interface. Supports PRA/PRI, EuroISDN voice and PPP, FR, HDLC data.
* Wildcard S100U - Single FXS interface connects to a standard analog
telephone.
* Wildcard TDM400P - Quad Modular FXS interface connects to standard
analog telephones.
* Wildcard TE410P - Quad T1/E1 switchable interface. Supports PRI and
RBS signalling, as well as PPP, FR, and HDLC data modes.
Non-zaptel compatible hardware
==============================
-- QuickNet, Inc.
http://www.quicknet.net
* Internet PhoneJack - Single FXS interface. Supports Linux telephony
interface. DSP compression built-in.
* Internet LineJack - Single FXS or FXO interface. Supports Linux
telephony interface.
Miscellaneous other interfaces
==============================
-- ISDN4Linux
http://www.isdn4linux.de/
* Any ISDN terminal adapter supported by isdn4linux should provide
connectivity.
-- ALSA
http://www.alsa-project.org
* Any ALSA compatible full-duplex sound card
-- OSS
http://www.opensound.com
* Any OSS compatible full-duplex sound card

554
Makefile
View File

@@ -11,217 +11,23 @@
# the GNU General Public License
#
.EXPORT_ALL_VARIABLES:
# Create OPTIONS variable
OPTIONS=
OSARCH=$(shell uname -s)
ifeq (${OSARCH},Linux)
PROC=$(shell uname -m)
ifeq ($(PROC),x86_64)
# You must have GCC 3.4 to use k8, otherwise use athlon
PROC=k8
#PROC=athlon
OPTIONS+=-m64
endif
ifeq ($(PROC),sparc64)
#The problem with sparc is the best stuff is in newer versions of gcc (post 3.0) only.
#This works for even old (2.96) versions of gcc and provides a small boost either way.
#A ultrasparc cpu is really v9 but the stock debian stable 3.0 gcc doesn't support it.
#So we go lowest common available by gcc and go a step down, still a step up from
#the default as we now have a better instruction set to work with. - Belgarath
PROC=ultrasparc
OPTIONS+=$(shell if $(CC) -mtune=$(PROC) -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-mtune=$(PROC)"; fi)
OPTIONS+=$(shell if $(CC) -mcpu=v8 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-mcpu=v8"; fi)
OPTIONS+=-fomit-frame-pointer
endif
MPG123TARG=linux
endif
ifeq ($(findstring BSD,${OSARCH}),BSD)
PROC=$(shell uname -m)
endif
MODULES_DIR=/usr/lib/asterisk/modules
# Pentium Pro Optimize
#PROC=i686
# Pentium Optimize
PROC=i586
# Pentium & VIA processors optimize
#PROC=i586
#PROC=k6
#PROC=ppc
PWD=$(shell pwd)
######### More GSM codec optimization
######### Uncomment to enable MMXTM optimizations for x86 architecture CPU's
######### which support MMX instructions. This should be newer pentiums,
######### ppro's, etc, as well as the AMD K6 and K7.
#K6OPT = -DK6OPT
#Tell gcc to optimize the asterisk's code
OPTIMIZE+=-O6
#Include debug symbols in the executables (-g) and profiling info (-pg)
DEBUG=-g #-pg
# If you are running a radio application, define RADIO_RELAX so that the DTMF
# will be received more reliably
#OPTIONS += -DRADIO_RELAX
# If you don't have a lot of memory (e.g. embedded Asterisk), uncomment the
# following to reduce the size of certain static buffers
#OPTIONS += -DLOW_MEMORY
# Optional debugging parameters
DEBUG_THREADS = #-DDEBUG_THREADS #-DDO_CRASH
# Uncomment next one to enable ast_frame tracing (for debugging)
TRACE_FRAMES = #-DTRACE_FRAMES
# Uncomment next one to enable malloc debugging
# You can view malloc debugging with:
# *CLI> show memory allocations [filename]
# *CLI> show memory summary [filename]
#
MALLOC_DEBUG = #-include $(PWD)/include/asterisk/astmm.h
# Where to install asterisk after compiling
# Default -> leave empty
INSTALL_PREFIX=
# Staging directory
# Files are copied here temporarily during the install process
# For example, make DESTDIR=/tmp/asterisk woud put things in
# /tmp/asterisk/etc/asterisk
DESTDIR=
# Original busydetect routine
BUSYDETECT = #-DBUSYDETECT
# Improved busydetect routine, comment the previous one if you use this one
BUSYDETECT+= -DBUSYDETECT_MARTIN
# Detect the busy signal looking only at tone lengths
# For example if you have 3 beeps 100ms tone, 100ms silence separated by 500 ms of silence
BUSYDETECT+= #-DBUSYDETECT_TONEONLY
# Inforce the detection of busy singal (get rid of false hangups)
# Don't use together with -DBUSYDETECT_TONEONLY
BUSYDETECT+= #-DBUSYDETECT_COMPARE_TONE_AND_SILENCE
ASTLIBDIR=$(INSTALL_PREFIX)/usr/lib/asterisk
ASTVARLIBDIR=$(INSTALL_PREFIX)/var/lib/asterisk
ASTETCDIR=$(INSTALL_PREFIX)/etc/asterisk
ASTSPOOLDIR=$(INSTALL_PREFIX)/var/spool/asterisk
ASTLOGDIR=$(INSTALL_PREFIX)/var/log/asterisk
ASTHEADERDIR=$(INSTALL_PREFIX)/usr/include/asterisk
ASTCONFPATH=$(ASTETCDIR)/asterisk.conf
ASTBINDIR=$(INSTALL_PREFIX)/usr/bin
ASTSBINDIR=$(INSTALL_PREFIX)/usr/sbin
ASTVARRUNDIR=$(INSTALL_PREFIX)/var/run
ASTMANDIR=$(INSTALL_PREFIX)/usr/share/man
MODULES_DIR=$(ASTLIBDIR)/modules
AGI_DIR=$(ASTVARLIBDIR)/agi-bin
INCLUDE=-Iinclude -I../include
CFLAGS=-pipe -Wall -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations $(DEBUG) $(INCLUDE) -D_REENTRANT -D_GNU_SOURCE #-DMAKE_VALGRIND_HAPPY
CFLAGS+=$(OPTIMIZE)
ifneq ($(PROC),ultrasparc)
CFLAGS=-pipe -Wall -Werror -Wmissing-prototypes -Wmissing-declarations -O6 $(DEBUG) $(INCLUDE) -D_REENTRANT
CFLAGS+=$(shell if $(CC) -march=$(PROC) -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=$(PROC)"; fi)
endif
CFLAGS+=$(shell if uname -m | grep -q ppc; then echo "-fsigned-char"; fi)
CFLAGS+=$(shell if [ -f /usr/include/osp/osp.h ]; then echo "-DOSP_SUPPORT -I/usr/include/osp" ; fi)
ifeq (${OSARCH},FreeBSD)
OSVERSION=$(shell make -V OSVERSION -f /usr/share/mk/bsd.port.subdir.mk)
CFLAGS+=$(shell if test ${OSVERSION} -lt 500016 ; then echo "-D_THREAD_SAFE"; fi)
LIBS+=$(shell if test ${OSVERSION} -lt 502102 ; then echo "-lc_r"; else echo "-pthread"; fi)
INCLUDE+=-I/usr/local/include
CFLAGS+=$(shell if [ -d /usr/local/include/spandsp ]; then echo "-I/usr/local/include/spandsp"; fi)
MPG123TARG=freebsd
endif # FreeBSD
ifeq (${OSARCH},NetBSD)
CFLAGS+=-pthread
INCLUDE+=-I/usr/local/include -I/usr/pkg/include
MPG123TARG=netbsd
endif
ifeq (${OSARCH},OpenBSD)
CFLAGS+=-pthread
endif
#Uncomment this to use the older DSP routines
#CFLAGS+=-DOLD_DSP_ROUTINES
CFLAGS+=$(shell if [ -f /usr/include/linux/zaptel.h ]; then echo "-DZAPTEL_OPTIMIZATIONS"; fi)
CFLAGS+=$(shell if [ -f /usr/local/include/zaptel.h ]; then echo "-DZAPTEL_OPTIMIZATIONS"; fi)
LIBEDIT=editline/libedit.a
ASTERISKVERSION=$(shell if [ -f .version ]; then cat .version; else if [ -d CVS ]; then if [ -f CVS/Tag ] ; then echo "CVS-`sed 's/^T//g' CVS/Tag`-`date +"%D-%T"`"; else echo "CVS-HEAD-`date +"%D-%T"`"; fi; fi; fi)
HTTPDIR=$(shell if [ -d /var/www ]; then echo "/var/www"; else echo "/home/httpd"; fi)
RPMVERSION=$(shell if [ -f .version ]; then sed 's/[-\/:]/_/g' .version; else echo "unknown" ; fi)
CFLAGS+=-DASTERISK_VERSION=\"$(ASTERISKVERSION)\"
CFLAGS+=-DINSTALL_PREFIX=\"$(INSTALL_PREFIX)\"
CFLAGS+=-DASTETCDIR=\"$(ASTETCDIR)\"
CFLAGS+=-DASTLIBDIR=\"$(ASTLIBDIR)\"
CFLAGS+=-DASTVARLIBDIR=\"$(ASTVARLIBDIR)\"
CFLAGS+=-DASTVARRUNDIR=\"$(ASTVARRUNDIR)\"
CFLAGS+=-DASTSPOOLDIR=\"$(ASTSPOOLDIR)\"
CFLAGS+=-DASTLOGDIR=\"$(ASTLOGDIR)\"
CFLAGS+=-DASTCONFPATH=\"$(ASTCONFPATH)\"
CFLAGS+=-DASTMODDIR=\"$(MODULES_DIR)\"
CFLAGS+=-DASTAGIDIR=\"$(AGI_DIR)\"
CFLAGS+= $(DEBUG_THREADS)
CFLAGS+= $(TRACE_FRAMES)
CFLAGS+= $(MALLOC_DEBUG)
CFLAGS+= $(BUSYDETECT)
CFLAGS+= $(OPTIONS)
CFLAGS+=# -fomit-frame-pointer
SUBDIRS=res channels pbx apps codecs formats agi cdr astman stdtime
ifeq (${OSARCH},Linux)
LIBS=-ldl -lpthread
endif
LIBS+=-lncurses -lm
ifeq (${OSARCH},Linux)
LIBS+=-lresolv #-lnjamd
endif
ifeq (${OSARCH},Darwin)
LIBS+=-lresolv
endif
ifeq (${OSARCH},FreeBSD)
LIBS+=-lcrypto
endif
ifeq (${OSARCH},NetBSD)
LIBS+=-lpthread -lcrypto -lm -L/usr/local/lib -L/usr/pkg/lib -lncurses
endif
ifeq (${OSARCH},OpenBSD)
LIBS=-lcrypto -lpthread -lm -lncurses
endif
LIBS+=-lssl
OBJS=io.o sched.o logger.o frame.o loader.o config.o channel.o \
translate.o file.o say.o pbx.o cli.o md5.o term.o \
ulaw.o alaw.o callerid.o fskmodem.o image.o app.o \
cdr.o tdd.o acl.o rtp.o manager.o asterisk.o ast_expr.o \
dsp.o chanvars.o indications.o autoservice.o db.o privacy.o \
astmm.o enum.o srv.o dns.o aescrypt.o aestab.o aeskey.o \
utils.o
ifeq (${OSARCH},Darwin)
OBJS+=poll.o dlfcn.o
ASTLINK=-Wl,-dynamic
SOLINK=-dynamic -bundle -undefined suppress -force_flat_namespace
else
ASTLINK=-Wl,-E
SOLINK=-shared -Xlinker -x
endif
SUBDIRS=channels pbx apps codecs formats
LIBS=-ldl -lpthread -lreadline # -lefence
OBJS=io.o sched.o logger.o frame.o loader.o config.o channel.o translate.o file.o say.o pbx.o cli.o md5.o asterisk.o
CC=gcc
INSTALL=install
@@ -231,330 +37,68 @@ _all: all
@echo " + cannot be run before being installed by +"
@echo " + running: +"
@echo " + +"
@echo " + $(MAKE) install +"
@echo " + make install +"
@echo " + +"
@echo " +-------------------------------------------+"
all: depend asterisk subdirs
all: asterisk subdirs
editline/config.h:
cd editline && unset CFLAGS LIBS && ./configure ; \
editline/libedit.a: FORCE
cd editline && unset CFLAGS LIBS && test -f config.h || ./configure
$(MAKE) -C editline libedit.a
db1-ast/libdb1.a: FORCE
@if [ -d db1-ast ]; then \
$(MAKE) -C db1-ast libdb1.a ; \
else \
echo "You need to do a cvs update -d not just cvs update"; \
exit 1; \
fi
ifneq ($(wildcard .depend),)
include .depend
endif
.PHONY: _version
_version:
if [ -d CVS ] && ! [ -f .version ]; then echo $(ASTERISKVERSION) > .version; fi
.version: _version
.y.c:
bison $< --name-prefix=ast_yy -o $@
ast_expr.o: ast_expr.c
cli.o: cli.c build.h
asterisk.o: asterisk.c build.h
manpage: asterisk.8.gz
asterisk.8.gz: asterisk.sgml
rm -f asterisk.8
docbook2man asterisk.sgml
mv ./*.8 asterisk.8
gzip asterisk.8
ifneq ($(strip $(ASTERISKVERSION)),)
build.h: .version
./make_build_h
else
build.h:
./make_build_h
endif
stdtime/libtime.a: FORCE
@if [ -d stdtime ]; then \
$(MAKE) -C stdtime libtime.a ; \
else \
echo "You need to do a cvs update -d not just cvs update"; \
exit 1; \
fi
asterisk: editline/libedit.a db1-ast/libdb1.a stdtime/libtime.a $(OBJS)
$(CC) $(DEBUG) -o asterisk $(ASTLINK) $(OBJS) $(LIBEDIT) db1-ast/libdb1.a stdtime/libtime.a $(LIBS)
muted: muted.o
$(CC) -o muted muted.o
asterisk: $(OBJS)
gcc -o asterisk -rdynamic $(OBJS) $(LIBS)
subdirs:
for x in $(SUBDIRS); do $(MAKE) -C $$x || exit 1 ; done
clean:
for x in $(SUBDIRS); do $(MAKE) -C $$x clean || exit 1 ; done
rm -f *.o *.so asterisk .depend
rm -f build.h
rm -f ast_expr.c
@if [ -e editline/Makefile ]; then $(MAKE) -C editline distclean ; fi
@if [ -d mpg123-0.59r ]; then $(MAKE) -C mpg123-0.59r clean; fi
$(MAKE) -C db1-ast clean
$(MAKE) -C stdtime clean
rm -f *.o *.so asterisk
datafiles: all
mkdir -p $(DESTDIR)$(ASTVARLIBDIR)/sounds/digits
for x in sounds/digits/*.gsm; do \
if grep -q "^%`basename $$x`%" sounds.txt; then \
install -m 644 $$x $(DESTDIR)$(ASTVARLIBDIR)/sounds/digits ; \
else \
echo "No description for $$x"; \
exit 1; \
fi; \
mkdir -p /var/lib/asterisk/sounds/digits
for x in sounds/digits/*; do \
install $$x /var/lib/asterisk/sounds/digits ; \
done
mkdir -p $(DESTDIR)$(ASTVARLIBDIR)/sounds/letters
for x in sounds/letters/*.gsm; do \
if grep -q "^%`basename $$x`%" sounds.txt; then \
install -m 644 $$x $(DESTDIR)$(ASTVARLIBDIR)/sounds/letters ; \
else \
echo "No description for $$x"; \
exit 1; \
fi; \
for x in sounds/vm-* sounds/transfer* ; do \
install $$x /var/lib/asterisk/sounds ; \
done
mkdir -p $(DESTDIR)$(ASTVARLIBDIR)/sounds/phonetic
for x in sounds/phonetic/*.gsm; do \
if grep -q "^%`basename $$x`%" sounds.txt; then \
install -m 644 $$x $(DESTDIR)$(ASTVARLIBDIR)/sounds/phonetic ; \
else \
echo "No description for $$x"; \
exit 1; \
fi; \
done
for x in sounds/vm-* sounds/transfer* sounds/pbx-* sounds/ss-* sounds/beep* sounds/dir-* sounds/conf-* sounds/agent-* sounds/invalid* sounds/tt-* sounds/auth-* sounds/privacy-* sounds/queue-*; do \
if grep -q "^%`basename $$x`%" sounds.txt; then \
install -m 644 $$x $(DESTDIR)$(ASTVARLIBDIR)/sounds ; \
else \
echo "No description for $$x"; \
exit 1; \
fi; \
done
mkdir -p $(DESTDIR)$(ASTVARLIBDIR)/mohmp3
mkdir -p $(DESTDIR)$(ASTVARLIBDIR)/images
for x in images/*.jpg; do \
install -m 644 $$x $(DESTDIR)$(ASTVARLIBDIR)/images ; \
done
mkdir -p $(DESTDIR)$(AGI_DIR)
update:
@if [ -d CVS ]; then \
echo "Updating from CVS..." ; \
cvs -q -z3 update -Pd; \
rm -f .version; \
else \
echo "Not CVS"; \
fi
bininstall: all
mkdir -p $(DESTDIR)$(MODULES_DIR)
mkdir -p $(DESTDIR)$(ASTSBINDIR)
mkdir -p $(DESTDIR)$(ASTETCDIR)
mkdir -p $(DESTDIR)$(ASTBINDIR)
mkdir -p $(DESTDIR)$(ASTSBINDIR)
mkdir -p $(DESTDIR)$(ASTVARRUNDIR)
mkdir -p $(DESTDIR)$(ASTSPOOLDIR)/voicemail
mkdir -p $(DESTDIR)$(ASTSPOOLDIR)/tmp
install -m 755 asterisk $(DESTDIR)$(ASTSBINDIR)/
install -m 755 contrib/scripts/astgenkey $(DESTDIR)$(ASTSBINDIR)/
if [ ! -f $(DESTDIR)$(ASTSBINDIR)/safe_asterisk ]; then \
install -m 755 contrib/scripts/safe_asterisk $(DESTDIR)$(ASTSBINDIR)/ ;\
fi
install: all
mkdir -p $(MODULES_DIR)
for x in $(SUBDIRS); do $(MAKE) -C $$x install || exit 1 ; done
install -d $(DESTDIR)$(ASTHEADERDIR)
install -m 644 include/asterisk/*.h $(DESTDIR)$(ASTHEADERDIR)
rm -f $(DESTDIR)$(ASTVARLIBDIR)/sounds/vm
rm -f $(DESTDIR)$(ASTVARLIBDIR)/sounds/voicemail
if [ ! -h $(DESTDIR)$(ASTSPOOLDIR)/vm ] && [ -d $(DESTDIR)$(ASTSPOOLDIR)/vm ]; then \
mv $(DESTDIR)$(ASTSPOOLDIR)/vm $(DESTDIR)$(ASTSPOOLDIR)/voicemail/default; \
else \
mkdir -p $(DESTDIR)$(ASTSPOOLDIR)/voicemail/default; \
rm -f $(DESTDIR)$(ASTSPOOLDIR)/vm; \
fi
ln -s $(ASTSPOOLDIR)/voicemail/default $(DESTDIR)$(ASTSPOOLDIR)/vm
mkdir -p $(DESTDIR)$(ASTVARLIBDIR)/sounds
mkdir -p $(DESTDIR)$(ASTLOGDIR)/cdr-csv
mkdir -p $(DESTDIR)$(ASTVARLIBDIR)/keys
mkdir -p $(DESTDIR)$(ASTVARLIBDIR)/firmware
mkdir -p $(DESTDIR)$(ASTVARLIBDIR)/firmware/iax
mkdir -p $(DESTDIR)$(ASTMANDIR)/man8
install -m 644 keys/iaxtel.pub $(DESTDIR)$(ASTVARLIBDIR)/keys
install -m 644 keys/freeworlddialup.pub $(DESTDIR)$(ASTVARLIBDIR)/keys
install -m 644 asterisk.8.gz $(DESTDIR)$(ASTMANDIR)/man8
if [ -d contrib/firmware/iax ]; then \
install -m 644 contrib/firmware/iax/iaxy.bin $(DESTDIR)$(ASTVARLIBDIR)/firmware/iax/iaxy.bin; \
else \
echo "You need to do cvs update -d not just cvs update" ; \
fi
( cd $(DESTDIR)$(ASTVARLIBDIR)/sounds ; ln -s $(ASTSPOOLDIR)/vm . )
( cd $(DESTDIR)$(ASTVARLIBDIR)/sounds ; ln -s $(ASTSPOOLDIR)/voicemail . )
if [ -f mpg123-0.59r/mpg123 ]; then $(MAKE) -C mpg123-0.59r install; fi
install -d /usr/include/asterisk
install include/asterisk/*.h /usr/include/asterisk
rm -f /var/lib/asterisk/sounds/vm
mkdir -p /var/spool/asterisk/vm
rm -f /usr/lib/asterisk/modules/chan_ixj.so
mkdir -p /var/lib/asterisk/sounds
( cd /var/lib/asterisk/sounds ; ln -s ../../../spool/asterisk/vm . )
@echo " +---- Asterisk Installation Complete -------+"
@echo " + +"
@echo " + YOU MUST READ THE SECURITY DOCUMENT +"
@echo " + +"
@echo " + Asterisk has successfully been installed. +"
@echo " + If you would like to install the sample +"
@echo " + configuration files (overwriting any +"
@echo " + existing config files), run: +"
@echo " + +"
@echo " + $(MAKE) samples +"
@echo " + +"
@echo " +----------------- or ---------------------+"
@echo " + +"
@echo " + You can go ahead and install the asterisk +"
@echo " + program documentation now or later run: +"
@echo " + +"
@echo " + $(MAKE) progdocs +"
@echo " + +"
@echo " + **Note** This requires that you have +"
@echo " + doxygen installed on your local system +"
@echo " +-------------------------------------------+"
install: all datafiles bininstall
upgrade: all bininstall
adsi: all
mkdir -p $(DESTDIR)$(ASTETCDIR)
for x in configs/*.adsi; do \
if ! [ -f $(DESTDIR)$(ASTETCDIRX)/$$x ]; then \
install -m 644 $$x $(DESTDIR)$(ASTETCDIR)/`basename $$x` ; \
fi ; \
done
samples: all datafiles adsi
mkdir -p $(DESTDIR)$(ASTETCDIR)
for x in configs/*.sample; do \
if [ -f $(DESTDIR)$(ASTETCDIR)/`basename $$x .sample` ]; then \
mv -f $(DESTDIR)$(ASTETCDIR)/`basename $$x .sample` $(DESTDIR)$(ASTETCDIR)/`basename $$x .sample`.old ; \
fi ; \
install -m 644 $$x $(DESTDIR)$(ASTETCDIR)/`basename $$x .sample` ;\
done
echo "[directories]" > $(DESTDIR)$(ASTETCDIR)/asterisk.conf
echo "astetcdir => $(ASTETCDIR)" >> $(DESTDIR)$(ASTETCDIR)/asterisk.conf
echo "astmoddir => $(MODULES_DIR)" >> $(DESTDIR)$(ASTETCDIR)/asterisk.conf
echo "astvarlibdir => $(ASTVARLIBDIR)" >> $(DESTDIR)$(ASTETCDIR)/asterisk.conf
echo "astagidir => $(AGI_DIR)" >> $(DESTDIR)$(ASTETCDIR)/asterisk.conf
echo "astspooldir => $(ASTSPOOLDIR)" >> $(DESTDIR)$(ASTETCDIR)/asterisk.conf
echo "astrundir => $(ASTVARRUNDIR)" >> $(DESTDIR)$(ASTETCDIR)/asterisk.conf
echo "astlogdir => $(ASTLOGDIR)" >> $(DESTDIR)$(ASTETCDIR)/asterisk.conf
for x in sounds/demo-*; do \
if grep -q "^%`basename $$x`%" sounds.txt; then \
install -m 644 $$x $(DESTDIR)$(ASTVARLIBDIR)/sounds ; \
else \
echo "No description for $$x"; \
exit 1; \
fi; \
done
for x in sounds/*.mp3; do \
install -m 644 $$x $(DESTDIR)$(ASTVARLIBDIR)/mohmp3 ; \
done
rm -f $(DESTDIR)$(ASTVARLIBDIR)/mohmp3/sample-hold.mp3
mkdir -p $(DESTDIR)$(ASTSPOOLDIR)/voicemail/default/1234/INBOX
:> $(DESTDIR)$(ASTSPOOLDIR)/voicemail/default/1234/unavail.gsm
for x in vm-theperson digits/1 digits/2 digits/3 digits/4 vm-isunavail; do \
cat $(DESTDIR)$(ASTVARLIBDIR)/sounds/$$x.gsm >> $(DESTDIR)$(ASTSPOOLDIR)/voicemail/default/1234/unavail.gsm ; \
done
:> $(DESTDIR)$(ASTSPOOLDIR)/voicemail/default/1234/busy.gsm
for x in vm-theperson digits/1 digits/2 digits/3 digits/4 vm-isonphone; do \
cat $(DESTDIR)$(ASTVARLIBDIR)/sounds/$$x.gsm >> $(DESTDIR)$(ASTSPOOLDIR)/voicemail/default/1234/busy.gsm ; \
done
webvmail:
@[ -d $(DESTDIR)$(HTTPDIR) ] || ( echo "No HTTP directory" && exit 1 )
@[ -d $(DESTDIR)$(HTTPDIR)/html ] || ( echo "No http directory" && exit 1 )
@[ -d $(DESTDIR)$(HTTPDIR)/cgi-bin ] || ( echo "No cgi-bin directory" && exit 1 )
install -m 4755 -o root -g root contrib/scripts/vmail.cgi $(DESTDIR)$(HTTPDIR)/cgi-bin/vmail.cgi
mkdir -p $(DESTDIR)$(HTTPDIR)/html/_asterisk
for x in images/*.gif; do \
install -m 644 $$x $(DESTDIR)$(HTTPDIR)/html/_asterisk/; \
done
@echo " +--------- Asterisk Web Voicemail ----------+"
@echo " + +"
@echo " + Asterisk Web Voicemail is installed in +"
@echo " + your cgi-bin directory. IT USES A SETUID +"
@echo " + ROOT PERL SCRIPT, SO IF YOU DON'T LIKE +"
@echo " + THAT, UNINSTALL IT! +"
@echo " + make samples +"
@echo " + +"
@echo " +-------------------------------------------+"
mailbox:
./contrib/scripts/addmailbox
rpm: __rpm
__rpm: _version
rm -rf /tmp/asterisk ; \
mkdir -p /tmp/asterisk/redhat/RPMS/i386 ; \
$(MAKE) DESTDIR=/tmp/asterisk install ; \
$(MAKE) DESTDIR=/tmp/asterisk samples ; \
mkdir -p /tmp/asterisk/etc/rc.d/init.d ; \
cp -f redhat/asterisk /tmp/asterisk/etc/rc.d/init.d/ ; \
sed "s/^Version:.*/Version: $(RPMVERSION)/g" redhat/asterisk.spec > asterisk.spec ; \
rpmbuild --rcfile /usr/lib/rpm/rpmrc:redhat/rpmrc -bb asterisk.spec
progdocs:
doxygen contrib/asterisk-ng-doxygen
mpg123:
@wget -V >/dev/null || (echo "You need wget" ; false )
[ -f mpg123-0.59r.tar.gz ] || wget http://www.mpg123.de/mpg123/mpg123-0.59r.tar.gz
[ -d mpg123-0.59r ] || tar xfz mpg123-0.59r.tar.gz
$(MAKE) -C mpg123-0.59r $(MPG123TARG)
config:
if [ -d /etc/rc.d/init.d ]; then \
install -m 755 contrib/init.d/rc.redhat.asterisk /etc/rc.d/init.d/asterisk; \
/sbin/chkconfig --add asterisk; \
elif [ -d /etc/init.d ]; then \
install -m 755 init.asterisk /etc/init.d/asterisk; \
fi
dont-optimize:
$(MAKE) OPTIMIZE= K6OPT= install
valgrind: dont-optimize
depend: .depend
for x in $(SUBDIRS); do $(MAKE) -C $$x depend || exit 1 ; done
.depend:
@if ! which mpg123 &>/dev/null ; then \
echo "*** You don't have mpg123 installed. You're going to need ***";\
echo "*** it if you want MusicOnHold ***";\
elif ! mpg123 --longhelp 2>&1 | grep .59r &>/dev/null ; then \
echo "*************************************************************";\
echo "*** You have the WRONG version of mpg123... you need .59r ***";\
echo "*** Use 'make mpg123' to get the right verison ***";\
echo "*************************************************************";\
fi
./mkdep ${CFLAGS} `ls *.c`
FORCE:
%_env:
$(MAKE) -C $(shell echo $@ | sed "s/_env//g") env
env:
env
samples: all datafiles
mkdir -p /etc/asterisk
for x in configs/*.sample; do \
if [ -f /etc/asterisk/`basename $$x .sample` ]; then \
mv -f /etc/asterisk/`basename $$x .sample` /etc/asterisk/`basename $$x .sample`.old ; \
fi ; \
install $$x /etc/asterisk/`basename $$x .sample` ;\
done
for x in sounds/demo-*; do \
install $$x /var/lib/asterisk/sounds; \
done
mkdir -p /var/spool/asterisk/vm/1234/INBOX
:> /var/lib/asterisk/sounds/vm/1234/unavail.gsm
for x in vm-theperson digits/1 digits/2 digits/3 digits/4 vm-isunavail; do \
cat /var/lib/asterisk/sounds/$$x.gsm >> /var/lib/asterisk/sounds/vm/1234/unavail.gsm ; \
done
:> /var/lib/asterisk/sounds/vm/1234/busy.gsm
for x in vm-theperson digits/1 digits/2 digits/3 digits/4 vm-isonphone; do \
cat /var/lib/asterisk/sounds/$$x.gsm >> /var/lib/asterisk/sounds/vm/1234/busy.gsm ; \
done

121
README
View File

@@ -1,72 +1,44 @@
The Asterisk Open Source PBX
by Mark Spencer <markster@digium.com>
Copyright (C) 2001-2004 Digium
by Mark Spencer <markster@linux-support.net>
Copyright (C) 1999, Mark Spencer
================================================================
* SECURITY
It is imperative that you read and fully understand the contents of
the SECURITY file before you attempt to configure an Asterisk server.
* WHAT IS ASTERISK
Asterisk is an Open Source PBX and telephony toolkit. It is, in a
sense, middleware between Internet and telephony channels on the bottom,
and Internet and telephony applications at the top. For more information
on the project itself, please visit the Asterisk home page at:
http://www.asterisk.org
In addition you'll find lot's of information compiled by the Asterisk
community on this Wiki:
http://www.voip-info.org/wiki-Asterisk
* LICENSING
Asterisk is distributed under GNU General Public License. The GPL also
must apply to all loadable modules as well, except as defined below.
Digium, Inc. (formerly Linux Support Services) retains copyright to all
of the core Asterisk system, and therefore can grant, at its sole discretion,
the ability for companies, individuals, or organizations to create proprietary
or Open Source (but non-GPL'd) modules which may be dynamically linked at
runtime with the portions of Asterisk which fall under our copyright
umbrella, or are distributed under more flexible licenses than GPL.
http://www.asteriskpbx.com
If you wish to use our code in other GPL programs, don't worry -- there
is no requirement that you provide the same exemption in your GPL'd
products (although if you've written a module for Asterisk we would
strongly encourage you to make the same exemption that we do).
Specific permission is also granted to OpenSSL and OpenH323 to link to
Asterisk.
If you have any questions, whatsoever, regarding our licensing policy,
please contact us.
Modules that are GPL-licensed and not available under Digium's
licensing scheme are added to the Asterisk-addons CVS module.
* REQUIRED COMPONENTS
== Linux ==
Currently, the Asterisk Open Source PBX is only known to run on the
Linux OS, although it may be portable to other UNIX-like operating systems
(like FreeBSD) as well.
as well.
== libaudiofile ==
If you want to use format_wav module, then you need a very recent
version of libaudiofile (at least version 0.2.0, or you can apply the
included patch. RPMS for the patched libaudiofile are available at:
ftp://ftp.asteriskpbx.com/pub/asterisk/support
* GETTING STARTED
First, be sure you've got supported hardware (but note that you don't need ANY hardware, not even a soundcard) to install and run Asterisk. Supported are:
First, be sure you've installed the required libaudiofile upgrade if
you want to use the non-GSM WAV format. Next, be sure you've got
supported hardware. To use Asterisk right now, you will need one of
the following:
* All Wildcard (tm) products from Digium (www.digium.com)
* QuickNet Internet PhoneJack and LineJack (http://www.quicknet.net)
* Full Duplex Sound Card supported by Linux
* Adtran Atlas 800 Plus
* ISDN4Linux compatible ISDN card
* Tormenta Dual T1 card (www.bsdtelephony.com.mx)
* QuickNet Internet PhoneJack
* Full Duplex Sound Card supported by Linux
Hint: CAPI compatible ISDN cards can be run using the add-on channel chan_capi.
So let's proceed:
Assuming you have one of these (most likely the third) you're ready to
proceed:
1) Run "make"
2) Run "make install"
@@ -76,16 +48,19 @@ the sample PBX, with demonstration extensions, etc. If so, run:
"make samples"
Doing so will overwrite any existing config files you have. If you are lacking a soundcard you won't be able to use the DIAL command on the console, though.
Doing so will overwrite any existing config files you have.
Finally, you can launch Asterisk with:
./asterisk -vvvc
If you get an error about unresolved symbols, install the updated
libaudiofile (available at ftp://ftp.asteriskpbx.com/pub/asterisk/support
You'll see a bunch of verbose messages fly by your screen as Asterisk
initializes (that's the "very very verbose" mode). When it's ready, if
you specified the "c" then you'll get a command line console, that looks
like this:
like this:
*CLI>
@@ -100,53 +75,7 @@ won't work right (not yet).
Feel free to look over the configuration files in /etc/asterisk, where
you'll find a lot of information about what you can do with Asterisk.
* ABOUT CONFIGURATION FILES
All Asterisk configuration files share a common format. Comments are
delimited by ';' (since '#' of course, being a DTMF digit, may occur in
many places). A configuration file is divided into sections whose names
appear in []'s. Each section typically contains two types of statements,
those of the form 'variable = value', and those of the form 'object =>
parameters'. Internally the use of '=' and '=>' is exactly the same, so
they're used only to help make the configuration file easier to
understand, and do not affect how it is actually parsed.
Entries of the form 'variable=value' set the value of some parameter in
asterisk. For example, in tormenta.conf, one might specify:
switchtype=national
In order to indicate to Asterisk that the switch they are connecting to is
of the type "national". In general, the parameter will apply to
instantiations which occur below its specification. For example, if the
configuration file read:
switchtype = national
channel => 1-4
channel => 10-12
switchtype = dms100
channel => 25-47
Then, the "national" switchtype would be applied to channels one through
four and channels 10 through 12, whereas the "dms100" switchtype would
apply to channels 25 through 47.
The "object => parameters" instantiates an object with the given
parameters. For example, the line "channel => 25-47" creates objects for
the channels 25 through 47 of the tormenta card, obtaining the settings
from the variables specified above.
* MORE INFORMATION
See the doc directory for more documentation.
Finally, you may wish to visit the web site and join the mailing list if
you're interested in getting more information.
http://www.asterisk.org/index.php?menu=support
Welcome to the growing worldwide community of Asterisk users!
Mark Spencer
Mark

View File

@@ -1,22 +0,0 @@
About Hold Music
================
These files were obtained from http://opsound.org, where the authors placed them
under the Creative Commons Attribution-Share Alike 2.5 license, a copy of which
may be found at http://creativecommons.org.
Credits
================
macroform-cold_day - Paul Shuler (Macroform)
paulshuler@gmail.com - http://macroform.bandcamp.com/
macroform-robot_dity - Paul Shuler (Macroform)
paulshuler@gmail.com - http://macroform.bandcamp.com/
macroform-the_simplicity - Paul Shuler (Macroform)
paulshuler@gmail.com - http://macroform.bandcamp.com/
manolo_camp-morning_coffee - Manolo Camp
beatbastard@gmx.net - http://ccmixter.org/people/ManoloCamp
reno_project-system - Reno Project
renoproject@hotmail.com - http://www.jamendo.com/en/album/23661

View File

@@ -1,41 +0,0 @@
==== Security Notes with Asterisk ====
PLEASE READ THE FOLLOWING IMPORTANT SECURITY RELATED INFORMATION.
IMPROPER CONFIGURATION OF ASTERISK COULD ALLOW UNAUTHORIZED USE OF YOUR
FACILITIES, POTENTIALLY INCURRING SUBSTANTIAL CHARGES.
First and foremost remember this:
USE THE EXTENSION CONTEXTS TO ISOLATE OUTGOING OR TOLL SERVICES FROM ANY
INCOMING CONNECTIONS.
You should consider that if any channel, incoming line, etc can enter an
extension context that it has the capability of accessing any extension
within that context.
Therefore, you should NOT allow access to outgoing or toll services in
contexts that are accessible (especially without a password) from incoming
channels, be they IAX channels, FX or other trunks, or even untrusted
stations within you network. In particular, never ever put outgoing toll
services in the "default" context. To make things easier, you can include
the "default" context within other private contexts by using:
include => default
in the appropriate section. A well designed PBX might look like this:
[longdistance]
exten => _91NXXNXXXXXX,1,Dial(Zap/g2/${EXTEN:1})
include => local
[local]
exten => _9NXXNXXX,1,Dial(Zap/g2/${EXTEN:1})
include => default
[default]
exten => 6123,Dial(Zap/1)
DON'T FORGET TO TAKE THE DEMO CONTEXT OUT OF YOUR DEFAULT CONTEXT. There
isn't really a security reason, it just will keep people from wanting to
play with your asterisk setup remotely.

409
acl.c
View File

@@ -1,409 +0,0 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* Various sorts of access control
*
* Copyright (C) 1999, Mark Spencer
*
* Mark Spencer <markster@linux-support.net>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <signal.h>
#include <errno.h>
#include <unistd.h>
#include <asterisk/acl.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <asterisk/utils.h>
#include <asterisk/lock.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netdb.h>
#include <net/if.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <sys/ioctl.h>
#if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__)
#include <fcntl.h>
#include <net/route.h>
AST_MUTEX_DEFINE_STATIC(routeseq_lock);
#endif
struct ast_ha {
/* Host access rule */
struct in_addr netaddr;
struct in_addr netmask;
int sense;
struct ast_ha *next;
};
/* Default IP - if not otherwise set, don't breathe garbage */
static struct in_addr __ourip = { 0x00000000 };
struct my_ifreq {
char ifrn_name[IFNAMSIZ]; /* Interface name, e.g. "eth0", "ppp0", etc. */
struct sockaddr_in ifru_addr;
};
/* Free HA structure */
void ast_free_ha(struct ast_ha *ha)
{
struct ast_ha *hal;
while(ha) {
hal = ha;
ha = ha->next;
free(hal);
}
}
/* Copy HA structure */
static void ast_copy_ha(struct ast_ha *from, struct ast_ha *to)
{
memcpy(&to->netaddr, &from->netaddr, sizeof(from->netaddr));
memcpy(&to->netmask, &from->netmask, sizeof(from->netmask));
to->sense = from->sense;
}
/* Create duplicate of ha structure */
static struct ast_ha *ast_duplicate_ha(struct ast_ha *original)
{
struct ast_ha *new_ha = malloc(sizeof(struct ast_ha));
/* Copy from original to new object */
ast_copy_ha(original, new_ha);
return(new_ha);
}
/* Create duplicate HA link list */
/* Used in chan_sip2 templates */
struct ast_ha *ast_duplicate_ha_list(struct ast_ha *original)
{
struct ast_ha *start=original;
struct ast_ha *ret = NULL;
struct ast_ha *link,*prev=NULL;
while(start) {
link = ast_duplicate_ha(start); /* Create copy of this object */
if (prev)
prev->next = link; /* Link previous to this object */
if (!ret)
ret = link; /* Save starting point */
start = start->next; /* Go to next object */
prev = link; /* Save pointer to this object */
}
return (ret); /* Return start of list */
}
struct ast_ha *ast_append_ha(char *sense, char *stuff, struct ast_ha *path)
{
struct ast_ha *ha = malloc(sizeof(struct ast_ha));
char *nm="255.255.255.255";
char tmp[256] = "";
struct ast_ha *prev = NULL;
struct ast_ha *ret;
int x,z;
unsigned int y;
ret = path;
while(path) {
prev = path;
path = path->next;
}
if (ha) {
strncpy(tmp, stuff, sizeof(tmp) - 1);
nm = strchr(tmp, '/');
if (!nm)
nm = "255.255.255.255";
else {
*nm = '\0';
nm++;
}
if (!strchr(nm, '.')) {
if ((sscanf(nm, "%i", &x) == 1) && (x >= 0) && (x <= 32)) {
y = 0;
for (z=0;z<x;z++) {
y >>= 1;
y |= 0x80000000;
}
ha->netmask.s_addr = htonl(y);
}
} else if (!inet_aton(nm, &ha->netmask)) {
ast_log(LOG_WARNING, "%s not a valid netmask\n", nm);
free(ha);
return path;
}
if (!inet_aton(tmp, &ha->netaddr)) {
ast_log(LOG_WARNING, "%s not a valid IP\n", tmp);
free(ha);
return path;
}
ha->netaddr.s_addr &= ha->netmask.s_addr;
if (!strncasecmp(sense, "p", 1)) {
ha->sense = AST_SENSE_ALLOW;
} else {
ha->sense = AST_SENSE_DENY;
}
ha->next = NULL;
if (prev)
prev->next = ha;
else
ret = ha;
}
ast_log(LOG_DEBUG, "%s/%s appended to acl for peer\n",stuff, nm);
return ret;
}
int ast_apply_ha(struct ast_ha *ha, struct sockaddr_in *sin)
{
/* Start optimistic */
int res = AST_SENSE_ALLOW;
while(ha) {
char iabuf[INET_ADDRSTRLEN];
char iabuf2[INET_ADDRSTRLEN];
/* DEBUG */
ast_log(LOG_DEBUG,
"##### Testing %s with %s\n",
ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr),
ast_inet_ntoa(iabuf2, sizeof(iabuf2), ha->netaddr));
/* For each rule, if this address and the netmask = the net address
apply the current rule */
if ((sin->sin_addr.s_addr & ha->netmask.s_addr) == (ha->netaddr.s_addr))
res = ha->sense;
ha = ha->next;
}
return res;
}
int ast_get_ip(struct sockaddr_in *sin, char *value)
{
struct hostent *hp;
struct ast_hostent ahp;
hp = ast_gethostbyname(value, &ahp);
if (hp) {
memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr));
} else {
ast_log(LOG_WARNING, "Unable to lookup '%s'\n", value);
return -1;
}
return 0;
}
/* iface is the interface (e.g. eth0); address is the return value */
int ast_lookup_iface(char *iface, struct in_addr *address) {
int mysock, res = 0;
struct my_ifreq ifreq;
memset(&ifreq, 0, sizeof(ifreq));
strncpy(ifreq.ifrn_name,iface,sizeof(ifreq.ifrn_name) - 1);
mysock = socket(PF_INET,SOCK_DGRAM,IPPROTO_IP);
res = ioctl(mysock,SIOCGIFADDR,&ifreq);
close(mysock);
if (res < 0) {
ast_log(LOG_WARNING, "Unable to get IP of %s: %s\n", iface, strerror(errno));
memcpy((char *)address,(char *)&__ourip,sizeof(__ourip));
return -1;
} else {
memcpy((char *)address,(char *)&ifreq.ifru_addr.sin_addr,sizeof(ifreq.ifru_addr.sin_addr));
return 0;
}
}
int ast_ouraddrfor(struct in_addr *them, struct in_addr *us)
{
#if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__)
struct sockaddr_in *sin;
struct sockaddr *sa;
struct {
struct rt_msghdr m_rtm;
char m_space[512];
} m_rtmsg;
char iabuf[INET_ADDRSTRLEN];
char *cp, *p;
int i, l, s, seq, flags;
pid_t pid = getpid();
static int routeseq; /* Protected by "routeseq_lock" mutex */
p = ast_strdupa(ast_inet_ntoa(iabuf, sizeof(iabuf), *them));
memset(us, 0, sizeof(struct in_addr));
memset(&m_rtmsg, 0, sizeof(m_rtmsg));
m_rtmsg.m_rtm.rtm_type = RTM_GET;
m_rtmsg.m_rtm.rtm_version = RTM_VERSION;
ast_mutex_lock(&routeseq_lock);
seq = ++routeseq;
ast_mutex_unlock(&routeseq_lock);
m_rtmsg.m_rtm.rtm_seq = seq;
m_rtmsg.m_rtm.rtm_addrs = RTA_DST | RTA_IFA;
m_rtmsg.m_rtm.rtm_msglen = sizeof(struct rt_msghdr) + sizeof(struct sockaddr_in);
sin = (struct sockaddr_in *)m_rtmsg.m_space;
sin->sin_family = AF_INET;
sin->sin_len = sizeof(struct sockaddr_in);
sin->sin_addr = *them;
if ((s = socket(PF_ROUTE, SOCK_RAW, AF_UNSPEC)) < 0) {
ast_log(LOG_ERROR, "Error opening routing socket\n");
return -1;
}
flags = fcntl(s, F_GETFL);
fcntl(s, F_SETFL, flags | O_NONBLOCK);
if (write(s, (char *)&m_rtmsg, m_rtmsg.m_rtm.rtm_msglen) < 0) {
ast_log(LOG_ERROR, "Error writing to routing socket: %s\n", strerror(errno));
close(s);
return -1;
}
do {
l = read(s, (char *)&m_rtmsg, sizeof(m_rtmsg));
} while (l > 0 && (m_rtmsg.m_rtm.rtm_seq != seq || m_rtmsg.m_rtm.rtm_pid != pid));
if (l < 0) {
if (errno != EAGAIN)
ast_log(LOG_ERROR, "Error reading from routing socket\n");
close(s);
return -1;
}
close(s);
if (m_rtmsg.m_rtm.rtm_version != RTM_VERSION) {
ast_log(LOG_ERROR, "Unsupported route socket protocol version\n");
return -1;
}
if (m_rtmsg.m_rtm.rtm_msglen != l)
ast_log(LOG_WARNING, "Message length mismatch, in packet %d, returned %d\n",
m_rtmsg.m_rtm.rtm_msglen, l);
if (m_rtmsg.m_rtm.rtm_errno) {
ast_log(LOG_ERROR, "RTM_GET got %s (%d)\n",
strerror(m_rtmsg.m_rtm.rtm_errno), m_rtmsg.m_rtm.rtm_errno);
return -1;
}
cp = (char *)m_rtmsg.m_space;
if (m_rtmsg.m_rtm.rtm_addrs)
for (i = 1; i; i <<= 1)
if (m_rtmsg.m_rtm.rtm_addrs & i) {
sa = (struct sockaddr *)cp;
if (i == RTA_IFA && sa->sa_family == AF_INET) {
sin = (struct sockaddr_in *)sa;
*us = sin->sin_addr;
ast_log(LOG_DEBUG, "Found route to %s, output from our address %s.\n", p, ast_inet_ntoa(iabuf, sizeof(iabuf), *us));
return 0;
}
cp += sa->sa_len > 0 ?
(1 + ((sa->sa_len - 1) | (sizeof(long) - 1))) :
sizeof(long);
}
ast_log(LOG_DEBUG, "No route found for address %s!\n", p);
return -1;
#else
FILE *PROC;
unsigned int remote_ip;
int res = 1;
char line[256];
remote_ip = them->s_addr;
PROC = fopen("/proc/net/route","r");
if (!PROC) {
bzero(us,sizeof(struct in_addr));
return -1;
}
/* First line contains headers */
fgets(line,sizeof(line),PROC);
while (!feof(PROC)) {
char iface[256];
unsigned int dest, gateway, mask;
int i,fieldnum;
char *fields[40];
fgets(line,sizeof(line),PROC);
fieldnum = 0;
for (i=0;i<sizeof(line);i++) {
char *offset;
fields[fieldnum++] = line + i;
offset = strchr(line + i,'\t');
if (offset == NULL) {
/* Exit loop */
break;
} else if (fieldnum >= 9) {
/* Short-circuit: can't break at 8, since the end of field 7 is figured when fieldnum=8 */
break;
} else {
*offset = '\0';
i = offset - line;
}
}
if (fieldnum >= 8) {
sscanf(fields[0],"%s",iface);
sscanf(fields[1],"%x",&dest);
sscanf(fields[2],"%x",&gateway);
sscanf(fields[7],"%x",&mask);
#if 0
{ char iabuf[INET_ADDRSTRLEN];
printf("Addr: %s %08x Dest: %08x Mask: %08x\n", ast_inet_ntoa(iabuf, sizeof(iabuf), *them), remote_ip, dest, mask); }
#endif
/* Looks simple, but here is the magic */
if (((remote_ip & mask) ^ dest) == 0) {
res = ast_lookup_iface(iface,us);
break;
}
}
}
fclose(PROC);
if (res == 1) {
ast_log(LOG_WARNING, "Yikes! No default route?!!\n");
bzero(us,sizeof(struct in_addr));
return -2;
} else if (res) {
/* We've already warned in subroutine */
return -1;
}
return 0;
#endif
}
int ast_find_ourip(struct in_addr *ourip, struct sockaddr_in bindaddr)
{
char ourhost[256];
struct ast_hostent ahp;
struct hostent *hp;
struct in_addr saddr;
/* just use the bind address if it is nonzero */
if (ntohl(bindaddr.sin_addr.s_addr)) {
memcpy(ourip, &bindaddr.sin_addr, sizeof(*ourip));
return 0;
}
/* try to use our hostname */
if (gethostname(ourhost, sizeof(ourhost))) {
ast_log(LOG_WARNING, "Unable to get hostname\n");
} else {
hp = ast_gethostbyname(ourhost, &ahp);
if (hp) {
memcpy(ourip, hp->h_addr, sizeof(*ourip));
return 0;
}
}
/* A.ROOT-SERVERS.NET. */
if (inet_aton("198.41.0.4", &saddr) && !ast_ouraddrfor(&saddr, ourip))
return 0;
return -1;
}

View File

@@ -1,311 +0,0 @@
/*
---------------------------------------------------------------------------
Copyright (c) 2003, Dr Brian Gladman <brg@gladman.me.uk>, Worcester, UK.
All rights reserved.
LICENSE TERMS
The free distribution and use of this software in both source and binary
form is allowed (with or without changes) provided that:
1. distributions of this source code include the above copyright
notice, this list of conditions and the following disclaimer;
2. distributions in binary form include the above copyright
notice, this list of conditions and the following disclaimer
in the documentation and/or other associated materials;
3. the copyright holder's name is not used to endorse products
built using this software without specific written permission.
ALTERNATIVELY, provided that this notice is retained in full, this product
may be distributed under the terms of the GNU General Public License (GPL),
in which case the provisions of the GPL apply INSTEAD OF those given above.
DISCLAIMER
This software is provided 'as is' with no explicit or implied warranties
in respect of its properties, including, but not limited to, correctness
and/or fitness for purpose.
---------------------------------------------------------------------------
Issue Date: 26/08/2003
This file contains the code for implementing encryption and decryption
for AES (Rijndael) for block and key sizes of 16, 24 and 32 bytes. It
can optionally be replaced by code written in assembler using NASM. For
further details see the file aesopt.h
*/
#include "aesopt.h"
#if defined(__cplusplus)
extern "C"
{
#endif
#define si(y,x,k,c) (s(y,c) = word_in(x, c) ^ (k)[c])
#define so(y,x,c) word_out(y, c, s(x,c))
#if defined(ARRAYS)
#define locals(y,x) x[4],y[4]
#else
#define locals(y,x) x##0,x##1,x##2,x##3,y##0,y##1,y##2,y##3
#endif
#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
s(y,2) = s(x,2); s(y,3) = s(x,3);
#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3)
#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3)
#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3)
#if defined(ENCRYPTION) && !defined(AES_ASM)
/* Visual C++ .Net v7.1 provides the fastest encryption code when using
Pentium optimiation with small code but this is poor for decryption
so we need to control this with the following VC++ pragmas
*/
#if defined(_MSC_VER)
#pragma optimize( "s", on )
#endif
/* Given the column (c) of the output state variable, the following
macros give the input state variables which are needed in its
computation for each row (r) of the state. All the alternative
macros give the same end values but expand into different ways
of calculating these values. In particular the complex macro
used for dynamically variable block sizes is designed to expand
to a compile time constant whenever possible but will expand to
conditional clauses on some branches (I am grateful to Frank
Yellin for this construction)
*/
#define fwd_var(x,r,c)\
( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\
: r == 1 ? ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0))\
: r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\
: ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2)))
#if defined(FT4_SET)
#undef dec_fmvars
#define fwd_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,n),fwd_var,rf1,c))
#elif defined(FT1_SET)
#undef dec_fmvars
#define fwd_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,upr,t_use(f,n),fwd_var,rf1,c))
#else
#define fwd_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ fwd_mcol(no_table(x,t_use(s,box),fwd_var,rf1,c)))
#endif
#if defined(FL4_SET)
#define fwd_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,l),fwd_var,rf1,c))
#elif defined(FL1_SET)
#define fwd_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,ups,t_use(f,l),fwd_var,rf1,c))
#else
#define fwd_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ no_table(x,t_use(s,box),fwd_var,rf1,c))
#endif
aes_rval aes_encrypt(const void *in_blk, void *out_blk, const aes_encrypt_ctx cx[1])
{ aes_32t locals(b0, b1);
const aes_32t *kp = cx->ks;
#ifdef dec_fmvars
dec_fmvars; /* declare variables for fwd_mcol() if needed */
#endif
aes_32t nr = (kp[45] ^ kp[52] ^ kp[53] ? kp[52] : 14);
#ifdef AES_ERR_CHK
if( (nr != 10 || !(kp[0] | kp[3] | kp[4]))
&& (nr != 12 || !(kp[0] | kp[5] | kp[6]))
&& (nr != 14 || !(kp[0] | kp[7] | kp[8])) )
return aes_error;
#endif
state_in(b0, in_blk, kp);
#if (ENC_UNROLL == FULL)
switch(nr)
{
case 14:
round(fwd_rnd, b1, b0, kp + 1 * N_COLS);
round(fwd_rnd, b0, b1, kp + 2 * N_COLS);
kp += 2 * N_COLS;
case 12:
round(fwd_rnd, b1, b0, kp + 1 * N_COLS);
round(fwd_rnd, b0, b1, kp + 2 * N_COLS);
kp += 2 * N_COLS;
case 10:
round(fwd_rnd, b1, b0, kp + 1 * N_COLS);
round(fwd_rnd, b0, b1, kp + 2 * N_COLS);
round(fwd_rnd, b1, b0, kp + 3 * N_COLS);
round(fwd_rnd, b0, b1, kp + 4 * N_COLS);
round(fwd_rnd, b1, b0, kp + 5 * N_COLS);
round(fwd_rnd, b0, b1, kp + 6 * N_COLS);
round(fwd_rnd, b1, b0, kp + 7 * N_COLS);
round(fwd_rnd, b0, b1, kp + 8 * N_COLS);
round(fwd_rnd, b1, b0, kp + 9 * N_COLS);
round(fwd_lrnd, b0, b1, kp +10 * N_COLS);
}
#else
#if (ENC_UNROLL == PARTIAL)
{ aes_32t rnd;
for(rnd = 0; rnd < (nr >> 1) - 1; ++rnd)
{
kp += N_COLS;
round(fwd_rnd, b1, b0, kp);
kp += N_COLS;
round(fwd_rnd, b0, b1, kp);
}
kp += N_COLS;
round(fwd_rnd, b1, b0, kp);
#else
{ aes_32t rnd;
for(rnd = 0; rnd < nr - 1; ++rnd)
{
kp += N_COLS;
round(fwd_rnd, b1, b0, kp);
l_copy(b0, b1);
}
#endif
kp += N_COLS;
round(fwd_lrnd, b0, b1, kp);
}
#endif
state_out(out_blk, b0);
#ifdef AES_ERR_CHK
return aes_good;
#endif
}
#endif
#if defined(DECRYPTION) && !defined(AES_ASM)
/* Visual C++ .Net v7.1 provides the fastest encryption code when using
Pentium optimiation with small code but this is poor for decryption
so we need to control this with the following VC++ pragmas
*/
#if defined(_MSC_VER)
#pragma optimize( "t", on )
#endif
/* Given the column (c) of the output state variable, the following
macros give the input state variables which are needed in its
computation for each row (r) of the state. All the alternative
macros give the same end values but expand into different ways
of calculating these values. In particular the complex macro
used for dynamically variable block sizes is designed to expand
to a compile time constant whenever possible but will expand to
conditional clauses on some branches (I am grateful to Frank
Yellin for this construction)
*/
#define inv_var(x,r,c)\
( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\
: r == 1 ? ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2))\
: r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\
: ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0)))
#if defined(IT4_SET)
#undef dec_imvars
#define inv_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,n),inv_var,rf1,c))
#elif defined(IT1_SET)
#undef dec_imvars
#define inv_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,upr,t_use(i,n),inv_var,rf1,c))
#else
#define inv_rnd(y,x,k,c) (s(y,c) = inv_mcol((k)[c] ^ no_table(x,t_use(i,box),inv_var,rf1,c)))
#endif
#if defined(IL4_SET)
#define inv_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,l),inv_var,rf1,c))
#elif defined(IL1_SET)
#define inv_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,ups,t_use(i,l),inv_var,rf1,c))
#else
#define inv_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ no_table(x,t_use(i,box),inv_var,rf1,c))
#endif
aes_rval aes_decrypt(const void *in_blk, void *out_blk, const aes_decrypt_ctx cx[1])
{ aes_32t locals(b0, b1);
#ifdef dec_imvars
dec_imvars; /* declare variables for inv_mcol() if needed */
#endif
aes_32t nr = (cx->ks[45] ^ cx->ks[52] ^ cx->ks[53] ? cx->ks[52] : 14);
const aes_32t *kp = cx->ks + nr * N_COLS;
#ifdef AES_ERR_CHK
if( (nr != 10 || !(cx->ks[0] | cx->ks[3] | cx->ks[4]))
&& (nr != 12 || !(cx->ks[0] | cx->ks[5] | cx->ks[6]))
&& (nr != 14 || !(cx->ks[0] | cx->ks[7] | cx->ks[8])) )
return aes_error;
#endif
state_in(b0, in_blk, kp);
#if (DEC_UNROLL == FULL)
switch(nr)
{
case 14:
round(inv_rnd, b1, b0, kp - 1 * N_COLS);
round(inv_rnd, b0, b1, kp - 2 * N_COLS);
kp -= 2 * N_COLS;
case 12:
round(inv_rnd, b1, b0, kp - 1 * N_COLS);
round(inv_rnd, b0, b1, kp - 2 * N_COLS);
kp -= 2 * N_COLS;
case 10:
round(inv_rnd, b1, b0, kp - 1 * N_COLS);
round(inv_rnd, b0, b1, kp - 2 * N_COLS);
round(inv_rnd, b1, b0, kp - 3 * N_COLS);
round(inv_rnd, b0, b1, kp - 4 * N_COLS);
round(inv_rnd, b1, b0, kp - 5 * N_COLS);
round(inv_rnd, b0, b1, kp - 6 * N_COLS);
round(inv_rnd, b1, b0, kp - 7 * N_COLS);
round(inv_rnd, b0, b1, kp - 8 * N_COLS);
round(inv_rnd, b1, b0, kp - 9 * N_COLS);
round(inv_lrnd, b0, b1, kp - 10 * N_COLS);
}
#else
#if (DEC_UNROLL == PARTIAL)
{ aes_32t rnd;
for(rnd = 0; rnd < (nr >> 1) - 1; ++rnd)
{
kp -= N_COLS;
round(inv_rnd, b1, b0, kp);
kp -= N_COLS;
round(inv_rnd, b0, b1, kp);
}
kp -= N_COLS;
round(inv_rnd, b1, b0, kp);
#else
{ aes_32t rnd;
for(rnd = 0; rnd < nr - 1; ++rnd)
{
kp -= N_COLS;
round(inv_rnd, b1, b0, kp);
l_copy(b0, b1);
}
#endif
kp -= N_COLS;
round(inv_lrnd, b0, b1, kp);
}
#endif
state_out(out_blk, b0);
#ifdef AES_ERR_CHK
return aes_good;
#endif
}
#endif
#if defined(__cplusplus)
}
#endif

463
aeskey.c
View File

@@ -1,463 +0,0 @@
/*
---------------------------------------------------------------------------
Copyright (c) 2003, Dr Brian Gladman <brg@gladman.me.uk>, Worcester, UK.
All rights reserved.
LICENSE TERMS
The free distribution and use of this software in both source and binary
form is allowed (with or without changes) provided that:
1. distributions of this source code include the above copyright
notice, this list of conditions and the following disclaimer;
2. distributions in binary form include the above copyright
notice, this list of conditions and the following disclaimer
in the documentation and/or other associated materials;
3. the copyright holder's name is not used to endorse products
built using this software without specific written permission.
ALTERNATIVELY, provided that this notice is retained in full, this product
may be distributed under the terms of the GNU General Public License (GPL),
in which case the provisions of the GPL apply INSTEAD OF those given above.
DISCLAIMER
This software is provided 'as is' with no explicit or implied warranties
in respect of its properties, including, but not limited to, correctness
and/or fitness for purpose.
---------------------------------------------------------------------------
Issue Date: 26/08/2003
This file contains the code for implementing the key schedule for AES
(Rijndael) for block and key sizes of 16, 24, and 32 bytes. See aesopt.h
for further details including optimisation.
*/
#include "aesopt.h"
#if defined(__cplusplus)
extern "C"
{
#endif
/* Initialise the key schedule from the user supplied key. The key
length can be specified in bytes, with legal values of 16, 24
and 32, or in bits, with legal values of 128, 192 and 256. These
values correspond with Nk values of 4, 6 and 8 respectively.
The following macros implement a single cycle in the key
schedule generation process. The number of cycles needed
for each cx->n_col and nk value is:
nk = 4 5 6 7 8
------------------------------
cx->n_col = 4 10 9 8 7 7
cx->n_col = 5 14 11 10 9 9
cx->n_col = 6 19 15 12 11 11
cx->n_col = 7 21 19 16 13 14
cx->n_col = 8 29 23 19 17 14
*/
#define ke4(k,i) \
{ k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; k[4*(i)+5] = ss[1] ^= ss[0]; \
k[4*(i)+6] = ss[2] ^= ss[1]; k[4*(i)+7] = ss[3] ^= ss[2]; \
}
#define kel4(k,i) \
{ k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; k[4*(i)+5] = ss[1] ^= ss[0]; \
k[4*(i)+6] = ss[2] ^= ss[1]; k[4*(i)+7] = ss[3] ^= ss[2]; \
}
#define ke6(k,i) \
{ k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[6*(i)+ 7] = ss[1] ^= ss[0]; \
k[6*(i)+ 8] = ss[2] ^= ss[1]; k[6*(i)+ 9] = ss[3] ^= ss[2]; \
k[6*(i)+10] = ss[4] ^= ss[3]; k[6*(i)+11] = ss[5] ^= ss[4]; \
}
#define kel6(k,i) \
{ k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[6*(i)+ 7] = ss[1] ^= ss[0]; \
k[6*(i)+ 8] = ss[2] ^= ss[1]; k[6*(i)+ 9] = ss[3] ^= ss[2]; \
}
#define ke8(k,i) \
{ k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[8*(i)+ 9] = ss[1] ^= ss[0]; \
k[8*(i)+10] = ss[2] ^= ss[1]; k[8*(i)+11] = ss[3] ^= ss[2]; \
k[8*(i)+12] = ss[4] ^= ls_box(ss[3],0); k[8*(i)+13] = ss[5] ^= ss[4]; \
k[8*(i)+14] = ss[6] ^= ss[5]; k[8*(i)+15] = ss[7] ^= ss[6]; \
}
#define kel8(k,i) \
{ k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[8*(i)+ 9] = ss[1] ^= ss[0]; \
k[8*(i)+10] = ss[2] ^= ss[1]; k[8*(i)+11] = ss[3] ^= ss[2]; \
}
#if defined(ENCRYPTION_KEY_SCHEDULE)
#if defined(AES_128) || defined(AES_VAR)
aes_rval aes_encrypt_key128(const void *in_key, aes_encrypt_ctx cx[1])
{ aes_32t ss[4];
cx->ks[0] = ss[0] = word_in(in_key, 0);
cx->ks[1] = ss[1] = word_in(in_key, 1);
cx->ks[2] = ss[2] = word_in(in_key, 2);
cx->ks[3] = ss[3] = word_in(in_key, 3);
#if ENC_UNROLL == NONE
{ aes_32t i;
for(i = 0; i < ((11 * N_COLS - 1) / 4); ++i)
ke4(cx->ks, i);
}
#else
ke4(cx->ks, 0); ke4(cx->ks, 1);
ke4(cx->ks, 2); ke4(cx->ks, 3);
ke4(cx->ks, 4); ke4(cx->ks, 5);
ke4(cx->ks, 6); ke4(cx->ks, 7);
ke4(cx->ks, 8); kel4(cx->ks, 9);
#endif
/* cx->ks[45] ^ cx->ks[52] ^ cx->ks[53] is zero for a 256 bit */
/* key and must be non-zero for 128 and 192 bits keys */
cx->ks[53] = cx->ks[45] = 0;
cx->ks[52] = 10;
#ifdef AES_ERR_CHK
return aes_good;
#endif
}
#endif
#if defined(AES_192) || defined(AES_VAR)
aes_rval aes_encrypt_key192(const void *in_key, aes_encrypt_ctx cx[1])
{ aes_32t ss[6];
cx->ks[0] = ss[0] = word_in(in_key, 0);
cx->ks[1] = ss[1] = word_in(in_key, 1);
cx->ks[2] = ss[2] = word_in(in_key, 2);
cx->ks[3] = ss[3] = word_in(in_key, 3);
cx->ks[4] = ss[4] = word_in(in_key, 4);
cx->ks[5] = ss[5] = word_in(in_key, 5);
#if ENC_UNROLL == NONE
{ aes_32t i;
for(i = 0; i < (13 * N_COLS - 1) / 6; ++i)
ke6(cx->ks, i);
}
#else
ke6(cx->ks, 0); ke6(cx->ks, 1);
ke6(cx->ks, 2); ke6(cx->ks, 3);
ke6(cx->ks, 4); ke6(cx->ks, 5);
ke6(cx->ks, 6); kel6(cx->ks, 7);
#endif
/* cx->ks[45] ^ cx->ks[52] ^ cx->ks[53] is zero for a 256 bit */
/* key and must be non-zero for 128 and 192 bits keys */
cx->ks[53] = cx->ks[45];
cx->ks[52] = 12;
#ifdef AES_ERR_CHK
return aes_good;
#endif
}
#endif
#if defined(AES_256) || defined(AES_VAR)
aes_rval aes_encrypt_key256(const void *in_key, aes_encrypt_ctx cx[1])
{ aes_32t ss[8];
cx->ks[0] = ss[0] = word_in(in_key, 0);
cx->ks[1] = ss[1] = word_in(in_key, 1);
cx->ks[2] = ss[2] = word_in(in_key, 2);
cx->ks[3] = ss[3] = word_in(in_key, 3);
cx->ks[4] = ss[4] = word_in(in_key, 4);
cx->ks[5] = ss[5] = word_in(in_key, 5);
cx->ks[6] = ss[6] = word_in(in_key, 6);
cx->ks[7] = ss[7] = word_in(in_key, 7);
#if ENC_UNROLL == NONE
{ aes_32t i;
for(i = 0; i < (15 * N_COLS - 1) / 8; ++i)
ke8(cx->ks, i);
}
#else
ke8(cx->ks, 0); ke8(cx->ks, 1);
ke8(cx->ks, 2); ke8(cx->ks, 3);
ke8(cx->ks, 4); ke8(cx->ks, 5);
kel8(cx->ks, 6);
#endif
#ifdef AES_ERR_CHK
return aes_good;
#endif
}
#endif
#if defined(AES_VAR)
aes_rval aes_encrypt_key(const void *in_key, int key_len, aes_encrypt_ctx cx[1])
{
switch(key_len)
{
#ifdef AES_ERR_CHK
case 16: case 128: return aes_encrypt_key128(in_key, cx);
case 24: case 192: return aes_encrypt_key192(in_key, cx);
case 32: case 256: return aes_encrypt_key256(in_key, cx);
default: return aes_error;
#else
case 16: case 128: aes_encrypt_key128(in_key, cx); return;
case 24: case 192: aes_encrypt_key192(in_key, cx); return;
case 32: case 256: aes_encrypt_key256(in_key, cx); return;
#endif
}
}
#endif
#endif
#if defined(DECRYPTION_KEY_SCHEDULE)
#if DEC_ROUND == NO_TABLES
#define ff(x) (x)
#else
#define ff(x) inv_mcol(x)
#ifdef dec_imvars
#define d_vars dec_imvars
#endif
#endif
#if 1
#define kdf4(k,i) \
{ ss[0] = ss[0] ^ ss[2] ^ ss[1] ^ ss[3]; ss[1] = ss[1] ^ ss[3]; ss[2] = ss[2] ^ ss[3]; ss[3] = ss[3]; \
ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; ss[i % 4] ^= ss[4]; \
ss[4] ^= k[4*(i)]; k[4*(i)+4] = ff(ss[4]); ss[4] ^= k[4*(i)+1]; k[4*(i)+5] = ff(ss[4]); \
ss[4] ^= k[4*(i)+2]; k[4*(i)+6] = ff(ss[4]); ss[4] ^= k[4*(i)+3]; k[4*(i)+7] = ff(ss[4]); \
}
#define kd4(k,i) \
{ ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; ss[i % 4] ^= ss[4]; ss[4] = ff(ss[4]); \
k[4*(i)+4] = ss[4] ^= k[4*(i)]; k[4*(i)+5] = ss[4] ^= k[4*(i)+1]; \
k[4*(i)+6] = ss[4] ^= k[4*(i)+2]; k[4*(i)+7] = ss[4] ^= k[4*(i)+3]; \
}
#define kdl4(k,i) \
{ ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; ss[i % 4] ^= ss[4]; \
k[4*(i)+4] = (ss[0] ^= ss[1]) ^ ss[2] ^ ss[3]; k[4*(i)+5] = ss[1] ^ ss[3]; \
k[4*(i)+6] = ss[0]; k[4*(i)+7] = ss[1]; \
}
#else
#define kdf4(k,i) \
{ ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; k[4*(i)+ 4] = ff(ss[0]); ss[1] ^= ss[0]; k[4*(i)+ 5] = ff(ss[1]); \
ss[2] ^= ss[1]; k[4*(i)+ 6] = ff(ss[2]); ss[3] ^= ss[2]; k[4*(i)+ 7] = ff(ss[3]); \
}
#define kd4(k,i) \
{ ss[4] = ls_box(ss[3],3) ^ t_use(r,c)[i]; \
ss[0] ^= ss[4]; ss[4] = ff(ss[4]); k[4*(i)+ 4] = ss[4] ^= k[4*(i)]; \
ss[1] ^= ss[0]; k[4*(i)+ 5] = ss[4] ^= k[4*(i)+ 1]; \
ss[2] ^= ss[1]; k[4*(i)+ 6] = ss[4] ^= k[4*(i)+ 2]; \
ss[3] ^= ss[2]; k[4*(i)+ 7] = ss[4] ^= k[4*(i)+ 3]; \
}
#define kdl4(k,i) \
{ ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; k[4*(i)+ 4] = ss[0]; ss[1] ^= ss[0]; k[4*(i)+ 5] = ss[1]; \
ss[2] ^= ss[1]; k[4*(i)+ 6] = ss[2]; ss[3] ^= ss[2]; k[4*(i)+ 7] = ss[3]; \
}
#endif
#define kdf6(k,i) \
{ ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[6*(i)+ 6] = ff(ss[0]); ss[1] ^= ss[0]; k[6*(i)+ 7] = ff(ss[1]); \
ss[2] ^= ss[1]; k[6*(i)+ 8] = ff(ss[2]); ss[3] ^= ss[2]; k[6*(i)+ 9] = ff(ss[3]); \
ss[4] ^= ss[3]; k[6*(i)+10] = ff(ss[4]); ss[5] ^= ss[4]; k[6*(i)+11] = ff(ss[5]); \
}
#define kd6(k,i) \
{ ss[6] = ls_box(ss[5],3) ^ t_use(r,c)[i]; \
ss[0] ^= ss[6]; ss[6] = ff(ss[6]); k[6*(i)+ 6] = ss[6] ^= k[6*(i)]; \
ss[1] ^= ss[0]; k[6*(i)+ 7] = ss[6] ^= k[6*(i)+ 1]; \
ss[2] ^= ss[1]; k[6*(i)+ 8] = ss[6] ^= k[6*(i)+ 2]; \
ss[3] ^= ss[2]; k[6*(i)+ 9] = ss[6] ^= k[6*(i)+ 3]; \
ss[4] ^= ss[3]; k[6*(i)+10] = ss[6] ^= k[6*(i)+ 4]; \
ss[5] ^= ss[4]; k[6*(i)+11] = ss[6] ^= k[6*(i)+ 5]; \
}
#define kdl6(k,i) \
{ ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[6*(i)+ 6] = ss[0]; ss[1] ^= ss[0]; k[6*(i)+ 7] = ss[1]; \
ss[2] ^= ss[1]; k[6*(i)+ 8] = ss[2]; ss[3] ^= ss[2]; k[6*(i)+ 9] = ss[3]; \
}
#define kdf8(k,i) \
{ ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[8*(i)+ 8] = ff(ss[0]); ss[1] ^= ss[0]; k[8*(i)+ 9] = ff(ss[1]); \
ss[2] ^= ss[1]; k[8*(i)+10] = ff(ss[2]); ss[3] ^= ss[2]; k[8*(i)+11] = ff(ss[3]); \
ss[4] ^= ls_box(ss[3],0); k[8*(i)+12] = ff(ss[4]); ss[5] ^= ss[4]; k[8*(i)+13] = ff(ss[5]); \
ss[6] ^= ss[5]; k[8*(i)+14] = ff(ss[6]); ss[7] ^= ss[6]; k[8*(i)+15] = ff(ss[7]); \
}
#define kd8(k,i) \
{ aes_32t g = ls_box(ss[7],3) ^ t_use(r,c)[i]; \
ss[0] ^= g; g = ff(g); k[8*(i)+ 8] = g ^= k[8*(i)]; \
ss[1] ^= ss[0]; k[8*(i)+ 9] = g ^= k[8*(i)+ 1]; \
ss[2] ^= ss[1]; k[8*(i)+10] = g ^= k[8*(i)+ 2]; \
ss[3] ^= ss[2]; k[8*(i)+11] = g ^= k[8*(i)+ 3]; \
g = ls_box(ss[3],0); \
ss[4] ^= g; g = ff(g); k[8*(i)+12] = g ^= k[8*(i)+ 4]; \
ss[5] ^= ss[4]; k[8*(i)+13] = g ^= k[8*(i)+ 5]; \
ss[6] ^= ss[5]; k[8*(i)+14] = g ^= k[8*(i)+ 6]; \
ss[7] ^= ss[6]; k[8*(i)+15] = g ^= k[8*(i)+ 7]; \
}
#define kdl8(k,i) \
{ ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[8*(i)+ 8] = ss[0]; ss[1] ^= ss[0]; k[8*(i)+ 9] = ss[1]; \
ss[2] ^= ss[1]; k[8*(i)+10] = ss[2]; ss[3] ^= ss[2]; k[8*(i)+11] = ss[3]; \
}
#if defined(AES_128) || defined(AES_VAR)
aes_rval aes_decrypt_key128(const void *in_key, aes_decrypt_ctx cx[1])
{ aes_32t ss[5];
#ifdef d_vars
d_vars;
#endif
cx->ks[0] = ss[0] = word_in(in_key, 0);
cx->ks[1] = ss[1] = word_in(in_key, 1);
cx->ks[2] = ss[2] = word_in(in_key, 2);
cx->ks[3] = ss[3] = word_in(in_key, 3);
#if DEC_UNROLL == NONE
{ aes_32t i;
for(i = 0; i < (11 * N_COLS - 1) / 4; ++i)
ke4(cx->ks, i);
#if !(DEC_ROUND == NO_TABLES)
for(i = N_COLS; i < 10 * N_COLS; ++i)
cx->ks[i] = inv_mcol(cx->ks[i]);
#endif
}
#else
kdf4(cx->ks, 0); kd4(cx->ks, 1);
kd4(cx->ks, 2); kd4(cx->ks, 3);
kd4(cx->ks, 4); kd4(cx->ks, 5);
kd4(cx->ks, 6); kd4(cx->ks, 7);
kd4(cx->ks, 8); kdl4(cx->ks, 9);
#endif
/* cx->ks[45] ^ cx->ks[52] ^ cx->ks[53] is zero for a 256 bit */
/* key and must be non-zero for 128 and 192 bits keys */
cx->ks[53] = cx->ks[45] = 0;
cx->ks[52] = 10;
#ifdef AES_ERR_CHK
return aes_good;
#endif
}
#endif
#if defined(AES_192) || defined(AES_VAR)
aes_rval aes_decrypt_key192(const void *in_key, aes_decrypt_ctx cx[1])
{ aes_32t ss[7];
#ifdef d_vars
d_vars;
#endif
cx->ks[0] = ss[0] = word_in(in_key, 0);
cx->ks[1] = ss[1] = word_in(in_key, 1);
cx->ks[2] = ss[2] = word_in(in_key, 2);
cx->ks[3] = ss[3] = word_in(in_key, 3);
#if DEC_UNROLL == NONE
cx->ks[4] = ss[4] = word_in(in_key, 4);
cx->ks[5] = ss[5] = word_in(in_key, 5);
{ aes_32t i;
for(i = 0; i < (13 * N_COLS - 1) / 6; ++i)
ke6(cx->ks, i);
#if !(DEC_ROUND == NO_TABLES)
for(i = N_COLS; i < 12 * N_COLS; ++i)
cx->ks[i] = inv_mcol(cx->ks[i]);
#endif
}
#else
cx->ks[4] = ff(ss[4] = word_in(in_key, 4));
cx->ks[5] = ff(ss[5] = word_in(in_key, 5));
kdf6(cx->ks, 0); kd6(cx->ks, 1);
kd6(cx->ks, 2); kd6(cx->ks, 3);
kd6(cx->ks, 4); kd6(cx->ks, 5);
kd6(cx->ks, 6); kdl6(cx->ks, 7);
#endif
/* cx->ks[45] ^ cx->ks[52] ^ cx->ks[53] is zero for a 256 bit */
/* key and must be non-zero for 128 and 192 bits keys */
cx->ks[53] = cx->ks[45];
cx->ks[52] = 12;
#ifdef AES_ERR_CHK
return aes_good;
#endif
}
#endif
#if defined(AES_256) || defined(AES_VAR)
aes_rval aes_decrypt_key256(const void *in_key, aes_decrypt_ctx cx[1])
{ aes_32t ss[8];
#ifdef d_vars
d_vars;
#endif
cx->ks[0] = ss[0] = word_in(in_key, 0);
cx->ks[1] = ss[1] = word_in(in_key, 1);
cx->ks[2] = ss[2] = word_in(in_key, 2);
cx->ks[3] = ss[3] = word_in(in_key, 3);
#if DEC_UNROLL == NONE
cx->ks[4] = ss[4] = word_in(in_key, 4);
cx->ks[5] = ss[5] = word_in(in_key, 5);
cx->ks[6] = ss[6] = word_in(in_key, 6);
cx->ks[7] = ss[7] = word_in(in_key, 7);
{ aes_32t i;
for(i = 0; i < (15 * N_COLS - 1) / 8; ++i)
ke8(cx->ks, i);
#if !(DEC_ROUND == NO_TABLES)
for(i = N_COLS; i < 14 * N_COLS; ++i)
cx->ks[i] = inv_mcol(cx->ks[i]);
#endif
}
#else
cx->ks[4] = ff(ss[4] = word_in(in_key, 4));
cx->ks[5] = ff(ss[5] = word_in(in_key, 5));
cx->ks[6] = ff(ss[6] = word_in(in_key, 6));
cx->ks[7] = ff(ss[7] = word_in(in_key, 7));
kdf8(cx->ks, 0); kd8(cx->ks, 1);
kd8(cx->ks, 2); kd8(cx->ks, 3);
kd8(cx->ks, 4); kd8(cx->ks, 5);
kdl8(cx->ks, 6);
#endif
#ifdef AES_ERR_CHK
return aes_good;
#endif
}
#endif
#if defined(AES_VAR)
aes_rval aes_decrypt_key(const void *in_key, int key_len, aes_decrypt_ctx cx[1])
{
switch(key_len)
{
#ifdef AES_ERR_CHK
case 16: case 128: return aes_decrypt_key128(in_key, cx);
case 24: case 192: return aes_decrypt_key192(in_key, cx);
case 32: case 256: return aes_decrypt_key256(in_key, cx);
default: return aes_error;
#else
case 16: case 128: aes_decrypt_key128(in_key, cx); return;
case 24: case 192: aes_decrypt_key192(in_key, cx); return;
case 32: case 256: aes_decrypt_key256(in_key, cx); return;
#endif
}
}
#endif
#endif
#if defined(__cplusplus)
}
#endif

1047
aesopt.h

File diff suppressed because it is too large Load Diff

232
aestab.c
View File

@@ -1,232 +0,0 @@
/*
---------------------------------------------------------------------------
Copyright (c) 2003, Dr Brian Gladman <brg@gladman.me.uk>, Worcester, UK.
All rights reserved.
LICENSE TERMS
The free distribution and use of this software in both source and binary
form is allowed (with or without changes) provided that:
1. distributions of this source code include the above copyright
notice, this list of conditions and the following disclaimer;
2. distributions in binary form include the above copyright
notice, this list of conditions and the following disclaimer
in the documentation and/or other associated materials;
3. the copyright holder's name is not used to endorse products
built using this software without specific written permission.
ALTERNATIVELY, provided that this notice is retained in full, this product
may be distributed under the terms of the GNU General Public License (GPL),
in which case the provisions of the GPL apply INSTEAD OF those given above.
DISCLAIMER
This software is provided 'as is' with no explicit or implied warranties
in respect of its properties, including, but not limited to, correctness
and/or fitness for purpose.
---------------------------------------------------------------------------
Issue Date: 26/08/2003
*/
#if defined(__cplusplus)
extern "C"
{
#endif
#define DO_TABLES
#include "aesopt.h"
#if defined(FIXED_TABLES)
/* implemented in case of wrong call for fixed tables */
void gen_tabs(void)
{
}
#else /* dynamic table generation */
#if !defined(FF_TABLES)
/* Generate the tables for the dynamic table option
It will generally be sensible to use tables to compute finite
field multiplies and inverses but where memory is scarse this
code might sometimes be better. But it only has effect during
initialisation so its pretty unimportant in overall terms.
*/
/* return 2 ^ (n - 1) where n is the bit number of the highest bit
set in x with x in the range 1 < x < 0x00000200. This form is
used so that locals within fi can be bytes rather than words
*/
static aes_08t hibit(const aes_32t x)
{ aes_08t r = (aes_08t)((x >> 1) | (x >> 2));
r |= (r >> 2);
r |= (r >> 4);
return (r + 1) >> 1;
}
/* return the inverse of the finite field element x */
static aes_08t fi(const aes_08t x)
{ aes_08t p1 = x, p2 = BPOLY, n1 = hibit(x), n2 = 0x80, v1 = 1, v2 = 0;
if(x < 2) return x;
for(;;)
{
if(!n1) return v1;
while(n2 >= n1)
{
n2 /= n1; p2 ^= p1 * n2; v2 ^= v1 * n2; n2 = hibit(p2);
}
if(!n2) return v2;
while(n1 >= n2)
{
n1 /= n2; p1 ^= p2 * n1; v1 ^= v2 * n1; n1 = hibit(p1);
}
}
}
#endif
/* The forward and inverse affine transformations used in the S-box */
#define fwd_affine(x) \
(w = (aes_32t)x, w ^= (w<<1)^(w<<2)^(w<<3)^(w<<4), 0x63^(aes_08t)(w^(w>>8)))
#define inv_affine(x) \
(w = (aes_32t)x, w = (w<<1)^(w<<3)^(w<<6), 0x05^(aes_08t)(w^(w>>8)))
static int init = 0;
void gen_tabs(void)
{ aes_32t i, w;
#if defined(FF_TABLES)
aes_08t pow[512], log[256];
if(init) return;
/* log and power tables for GF(2^8) finite field with
WPOLY as modular polynomial - the simplest primitive
root is 0x03, used here to generate the tables
*/
i = 0; w = 1;
do
{
pow[i] = (aes_08t)w;
pow[i + 255] = (aes_08t)w;
log[w] = (aes_08t)i++;
w ^= (w << 1) ^ (w & 0x80 ? WPOLY : 0);
}
while (w != 1);
#else
if(init) return;
#endif
for(i = 0, w = 1; i < RC_LENGTH; ++i)
{
t_set(r,c)[i] = bytes2word(w, 0, 0, 0);
w = f2(w);
}
for(i = 0; i < 256; ++i)
{ aes_08t b;
b = fwd_affine(fi((aes_08t)i));
w = bytes2word(f2(b), b, b, f3(b));
#ifdef SBX_SET
t_set(s,box)[i] = b;
#endif
#ifdef FT1_SET /* tables for a normal encryption round */
t_set(f,n)[i] = w;
#endif
#ifdef FT4_SET
t_set(f,n)[0][i] = w;
t_set(f,n)[1][i] = upr(w,1);
t_set(f,n)[2][i] = upr(w,2);
t_set(f,n)[3][i] = upr(w,3);
#endif
w = bytes2word(b, 0, 0, 0);
#ifdef FL1_SET /* tables for last encryption round (may also */
t_set(f,l)[i] = w; /* be used in the key schedule) */
#endif
#ifdef FL4_SET
t_set(f,l)[0][i] = w;
t_set(f,l)[1][i] = upr(w,1);
t_set(f,l)[2][i] = upr(w,2);
t_set(f,l)[3][i] = upr(w,3);
#endif
#ifdef LS1_SET /* table for key schedule if t_set(f,l) above is */
t_set(l,s)[i] = w; /* not of the required form */
#endif
#ifdef LS4_SET
t_set(l,s)[0][i] = w;
t_set(l,s)[1][i] = upr(w,1);
t_set(l,s)[2][i] = upr(w,2);
t_set(l,s)[3][i] = upr(w,3);
#endif
b = fi(inv_affine((aes_08t)i));
w = bytes2word(fe(b), f9(b), fd(b), fb(b));
#ifdef IM1_SET /* tables for the inverse mix column operation */
t_set(i,m)[b] = w;
#endif
#ifdef IM4_SET
t_set(i,m)[0][b] = w;
t_set(i,m)[1][b] = upr(w,1);
t_set(i,m)[2][b] = upr(w,2);
t_set(i,m)[3][b] = upr(w,3);
#endif
#ifdef ISB_SET
t_set(i,box)[i] = b;
#endif
#ifdef IT1_SET /* tables for a normal decryption round */
t_set(i,n)[i] = w;
#endif
#ifdef IT4_SET
t_set(i,n)[0][i] = w;
t_set(i,n)[1][i] = upr(w,1);
t_set(i,n)[2][i] = upr(w,2);
t_set(i,n)[3][i] = upr(w,3);
#endif
w = bytes2word(b, 0, 0, 0);
#ifdef IL1_SET /* tables for last decryption round */
t_set(i,l)[i] = w;
#endif
#ifdef IL4_SET
t_set(i,l)[0][i] = w;
t_set(i,l)[1][i] = upr(w,1);
t_set(i,l)[2][i] = upr(w,2);
t_set(i,l)[3][i] = upr(w,3);
#endif
}
init = 1;
}
#endif
#if defined(__cplusplus)
}
#endif

View File

@@ -1,82 +0,0 @@
#!/usr/bin/perl
#
# Simple AGI application to play mp3's selected by a user both using
# xmms and over the phone itself.
#
$|=1;
while(<STDIN>) {
chomp;
last unless length($_);
if (/^agi_(\w+)\:\s+(.*)$/) {
$AGI{$1} = $2;
}
}
print STDERR "AGI Environment Dump:\n";
foreach $i (sort keys %AGI) {
print STDERR " -- $i = $AGI{$i}\n";
}
dbmopen(%DIGITS, "/var/lib/asterisk/mp3list", 0644) || die("Unable to open mp3list");;
sub checkresult {
my ($res) = @_;
my $retval;
$tests++;
chomp $res;
if ($res =~ /^200/) {
$res =~ /result=(-?[\w\*\#]+)/;
return $1;
} else {
return -1;
}
}
#print STDERR "1. Playing beep...\n";
#print "STREAM FILE beep \"\"\n";
#$result = <STDIN>;
#checkresult($result);
print STDERR "2. Getting song name...\n";
print "GET DATA demo-enterkeywords\n";
$result = <STDIN>;
$digitstr = checkresult($result);
if ($digitstr < 0) {
exit(1);
}
$digitstr =~ s/\*/ /g;
print STDERR "Resulting songname is $digitstr\n";
@searchwords = split (/\s+/, $digitstr);
print STDERR "Searchwords: " . join(':', @searchwords) . "\n";
foreach $key (sort keys %DIGITS) {
@words = split(/\s+/, $DIGITS{$key});
$match = 1;
foreach $search (@searchwords) {
$match = 0 unless grep(/$search/, @words);
}
if ($match > 0) {
print STDERR "File $key matches\n";
# Play a beep
print "STREAM FILE beep \"\"\n";
system("xmms", $key);
$result = <STDIN>;
if (&checkresult($result) < 0) {
exit 0;
}
print "EXEC MP3Player \"$key\"\n";
# print "WAIT FOR DIGIT 60000\n";
$result = <STDIN>;
if (&checkresult($result) < 0) {
exit 0;
}
print STDERR "Got here...\n";
}
}
print STDERR "4. Testing 'saynumber' of $digitstr...\n";
print "STREAM FILE demo-nomatch\"\"\n";
$result = <STDIN>;
checkresult($result);

View File

@@ -1,43 +0,0 @@
#
# Asterisk -- A telephony toolkit for Linux.
#
# Makefile for PBX frontends (dynamically loaded)
#
# Copyright (C) 1999, Mark Spencer
#
# Mark Spencer <markster@linux-support.net>
#
# This program is free software, distributed under the terms of
# the GNU General Public License
#
AGIS=agi-test.agi eagi-test eagi-sphinx-test
CFLAGS+=
all: depend $(AGIS)
install: all
mkdir -p $(DESTDIR)$(AGI_DIR)
for x in $(AGIS); do $(INSTALL) -m 755 $$x $(DESTDIR)$(AGI_DIR) ; done
eagi-test: eagi-test.o
$(CC) $(CFLAGS) -o eagi-test eagi-test.o
eagi-sphinx-test: eagi-sphinx-test.o
$(CC) $(CFLAGS) -o eagi-sphinx-test eagi-sphinx-test.o
clean:
rm -f *.so *.o look .depend eagi-test eagi-sphinx-test
%.so : %.o
$(CC) -shared -Xlinker -x -o $@ $<
ifneq ($(wildcard .depend),)
include .depend
endif
depend: .depend
.depend:
../mkdep $(CFLAGS) `ls *.c`

View File

@@ -1,79 +0,0 @@
#!/usr/bin/perl
use strict;
$|=1;
# Setup some variables
my %AGI; my $tests = 0; my $fail = 0; my $pass = 0;
while(<STDIN>) {
chomp;
last unless length($_);
if (/^agi_(\w+)\:\s+(.*)$/) {
$AGI{$1} = $2;
}
}
print STDERR "AGI Environment Dump:\n";
foreach my $i (sort keys %AGI) {
print STDERR " -- $i = $AGI{$i}\n";
}
sub checkresult {
my ($res) = @_;
my $retval;
$tests++;
chomp $res;
if ($res =~ /^200/) {
$res =~ /result=(-?\d+)/;
if (!length($1)) {
print STDERR "FAIL ($res)\n";
$fail++;
} else {
print STDERR "PASS ($1)\n";
$pass++;
}
} else {
print STDERR "FAIL (unexpected result '$res')\n";
$fail++;
}
}
print STDERR "1. Testing 'sendfile'...";
print "STREAM FILE beep \"\"\n";
my $result = <STDIN>;
&checkresult($result);
print STDERR "2. Testing 'sendtext'...";
print "SEND TEXT \"hello world\"\n";
my $result = <STDIN>;
&checkresult($result);
print STDERR "3. Testing 'sendimage'...";
print "SEND IMAGE asterisk-image\n";
my $result = <STDIN>;
&checkresult($result);
print STDERR "4. Testing 'saynumber'...";
print "SAY NUMBER 192837465 \"\"\n";
my $result = <STDIN>;
&checkresult($result);
print STDERR "5. Testing 'waitdtmf'...";
print "WAIT FOR DIGIT 1000\n";
my $result = <STDIN>;
&checkresult($result);
print STDERR "6. Testing 'record'...";
print "RECORD FILE testagi gsm 1234 3000\n";
my $result = <STDIN>;
&checkresult($result);
print STDERR "6a. Testing 'record' playback...";
print "STREAM FILE testagi \"\"\n";
my $result = <STDIN>;
&checkresult($result);
print STDERR "================== Complete ======================\n";
print STDERR "$tests tests completed, $pass passed, $fail failed\n";
print STDERR "==================================================\n";

View File

@@ -1,218 +0,0 @@
/*
* Extended AGI test application
*
* This code is released into public domain
* without any warranty of any kind.
*
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/select.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#define AUDIO_FILENO (STDERR_FILENO + 1)
#define SPHINX_HOST "192.168.1.108"
#define SPHINX_PORT 3460
static int sphinx_sock = -1;
static int connect_sphinx(void)
{
struct hostent *hp;
struct sockaddr_in sin;
int res;
hp = gethostbyname(SPHINX_HOST);
if (!hp) {
fprintf(stderr, "Unable to resolve '%s'\n", SPHINX_HOST);
return -1;
}
sphinx_sock = socket(PF_INET, SOCK_STREAM, 0);
if (sphinx_sock < 0) {
fprintf(stderr, "Unable to allocate socket: %s\n", strerror(errno));
return -1;
}
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = htons(SPHINX_PORT);
memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr));
if (connect(sphinx_sock, (struct sockaddr *)&sin, sizeof(sin))) {
fprintf(stderr, "Unable to connect on socket: %s\n", strerror(errno));
close(sphinx_sock);
sphinx_sock = -1;
return -1;
}
res = fcntl(sphinx_sock, F_GETFL);
if ((res < 0) || (fcntl(sphinx_sock, F_SETFL, res | O_NONBLOCK) < 0)) {
fprintf(stderr, "Unable to set flags on socket: %s\n", strerror(errno));
close(sphinx_sock);
sphinx_sock = -1;
return -1;
}
return 0;
}
static int read_environment(void)
{
char buf[256];
char *val;
/* Read environment */
for(;;) {
fgets(buf, sizeof(buf), stdin);
if (feof(stdin))
return -1;
buf[strlen(buf) - 1] = '\0';
/* Check for end of environment */
if (!strlen(buf))
return 0;
val = strchr(buf, ':');
if (!val) {
fprintf(stderr, "Invalid environment: '%s'\n", buf);
return -1;
}
*val = '\0';
val++;
val++;
/* Skip space */
fprintf(stderr, "Environment: '%s' is '%s'\n", buf, val);
/* Load into normal environment */
setenv(buf, val, 1);
}
/* Never reached */
return 0;
}
static char *wait_result(void)
{
fd_set fds;
int res;
int max;
static char astresp[256];
static char sphinxresp[256];
char audiobuf[4096];
for (;;) {
FD_ZERO(&fds);
FD_SET(STDIN_FILENO, &fds);
FD_SET(AUDIO_FILENO, &fds);
max = AUDIO_FILENO;
if (sphinx_sock > -1) {
FD_SET(sphinx_sock, &fds);
if (sphinx_sock > max)
max = sphinx_sock;
}
/* Wait for *some* sort of I/O */
res = select(max + 1, &fds, NULL, NULL, NULL);
if (res < 0) {
fprintf(stderr, "Error in select: %s\n", strerror(errno));
return NULL;
}
if (FD_ISSET(STDIN_FILENO, &fds)) {
fgets(astresp, sizeof(astresp), stdin);
if (feof(stdin)) {
fprintf(stderr, "Got hungup on apparently\n");
return NULL;
}
astresp[strlen(astresp) - 1] = '\0';
fprintf(stderr, "Ooh, got a response from Asterisk: '%s'\n", astresp);
return astresp;
}
if (FD_ISSET(AUDIO_FILENO, &fds)) {
res = read(AUDIO_FILENO, audiobuf, sizeof(audiobuf));
if (res > 0) {
if (sphinx_sock > -1)
write(sphinx_sock, audiobuf, res);
}
}
if ((sphinx_sock > -1) && FD_ISSET(sphinx_sock, &fds)) {
res = read(sphinx_sock, sphinxresp, sizeof(sphinxresp));
if (res > 0) {
fprintf(stderr, "Oooh, Sphinx found a token: '%s'\n", sphinxresp);
return sphinxresp;
} else if (res == 0) {
fprintf(stderr, "Hrm, lost sphinx, guess we're on our own\n");
close(sphinx_sock);
sphinx_sock = -1;
}
}
}
}
static char *run_command(char *command)
{
fprintf(stdout, "%s\n", command);
return wait_result();
}
static int run_script(void)
{
char *res;
res = run_command("STREAM FILE demo-enterkeywords 0123456789*#");
if (!res) {
fprintf(stderr, "Failed to execute command\n");
return -1;
}
fprintf(stderr, "1. Result is '%s'\n", res);
res = run_command("STREAM FILE demo-nomatch 0123456789*#");
if (!res) {
fprintf(stderr, "Failed to execute command\n");
return -1;
}
fprintf(stderr, "2. Result is '%s'\n", res);
res = run_command("SAY NUMBER 23452345 0123456789*#");
if (!res) {
fprintf(stderr, "Failed to execute command\n");
return -1;
}
fprintf(stderr, "3. Result is '%s'\n", res);
res = run_command("GET DATA demo-enterkeywords");
if (!res) {
fprintf(stderr, "Failed to execute command\n");
return -1;
}
fprintf(stderr, "4. Result is '%s'\n", res);
res = run_command("STREAM FILE auth-thankyou \"\"");
if (!res) {
fprintf(stderr, "Failed to execute command\n");
return -1;
}
fprintf(stderr, "5. Result is '%s'\n", res);
return 0;
}
int main(int argc, char *argv[])
{
char *tmp;
int ver = 0;
int subver = 0;
/* Setup stdin/stdout for line buffering */
setlinebuf(stdin);
setlinebuf(stdout);
if (read_environment()) {
fprintf(stderr, "Failed to read environment: %s\n", strerror(errno));
exit(1);
}
connect_sphinx();
tmp = getenv("agi_enhanced");
if (tmp) {
if (sscanf(tmp, "%d.%d", &ver, &subver) != 2)
ver = 0;
}
if (ver < 1) {
fprintf(stderr, "No enhanced AGI services available. Use EAGI, not AGI\n");
exit(1);
}
if (run_script())
return -1;
exit(0);
}

View File

@@ -1,161 +0,0 @@
/*
* Extended AGI test application
*
* This code is released into the public domain
* with no warranty of any kind
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/select.h>
#define AUDIO_FILENO (STDERR_FILENO + 1)
static int read_environment(void)
{
char buf[256];
char *val;
/* Read environment */
for(;;) {
fgets(buf, sizeof(buf), stdin);
if (feof(stdin))
return -1;
buf[strlen(buf) - 1] = '\0';
/* Check for end of environment */
if (!strlen(buf))
return 0;
val = strchr(buf, ':');
if (!val) {
fprintf(stderr, "Invalid environment: '%s'\n", buf);
return -1;
}
*val = '\0';
val++;
val++;
/* Skip space */
fprintf(stderr, "Environment: '%s' is '%s'\n", buf, val);
/* Load into normal environment */
setenv(buf, val, 1);
}
/* Never reached */
return 0;
}
static char *wait_result(void)
{
fd_set fds;
int res;
int bytes = 0;
static char astresp[256];
char audiobuf[4096];
for (;;) {
FD_ZERO(&fds);
FD_SET(STDIN_FILENO, &fds);
FD_SET(AUDIO_FILENO, &fds);
/* Wait for *some* sort of I/O */
res = select(AUDIO_FILENO + 1, &fds, NULL, NULL, NULL);
if (res < 0) {
fprintf(stderr, "Error in select: %s\n", strerror(errno));
return NULL;
}
if (FD_ISSET(STDIN_FILENO, &fds)) {
fgets(astresp, sizeof(astresp), stdin);
if (feof(stdin)) {
fprintf(stderr, "Got hungup on apparently\n");
return NULL;
}
astresp[strlen(astresp) - 1] = '\0';
fprintf(stderr, "Ooh, got a response from Asterisk: '%s'\n", astresp);
return astresp;
}
if (FD_ISSET(AUDIO_FILENO, &fds)) {
res = read(AUDIO_FILENO, audiobuf, sizeof(audiobuf));
if (res > 0) {
/* XXX Process the audio with sphinx here XXX */
#if 0
fprintf(stderr, "Got %d/%d bytes of audio\n", res, bytes);
#endif
bytes += res;
/* Prentend we detected some audio after 3 seconds */
if (bytes > 16000 * 3) {
return "Sample Message";
bytes = 0;
}
}
}
}
}
static char *run_command(char *command)
{
fprintf(stdout, "%s\n", command);
return wait_result();
}
static int run_script(void)
{
char *res;
res = run_command("STREAM FILE demo-enterkeywords 0123456789*#");
if (!res) {
fprintf(stderr, "Failed to execute command\n");
return -1;
}
fprintf(stderr, "1. Result is '%s'\n", res);
res = run_command("STREAM FILE demo-nomatch 0123456789*#");
if (!res) {
fprintf(stderr, "Failed to execute command\n");
return -1;
}
fprintf(stderr, "2. Result is '%s'\n", res);
res = run_command("SAY NUMBER 23452345 0123456789*#");
if (!res) {
fprintf(stderr, "Failed to execute command\n");
return -1;
}
fprintf(stderr, "3. Result is '%s'\n", res);
res = run_command("GET DATA demo-enterkeywords");
if (!res) {
fprintf(stderr, "Failed to execute command\n");
return -1;
}
fprintf(stderr, "4. Result is '%s'\n", res);
res = run_command("STREAM FILE auth-thankyou \"\"");
if (!res) {
fprintf(stderr, "Failed to execute command\n");
return -1;
}
fprintf(stderr, "5. Result is '%s'\n", res);
return 0;
}
int main(int argc, char *argv[])
{
char *tmp;
int ver = 0;
int subver = 0;
/* Setup stdin/stdout for line buffering */
setlinebuf(stdin);
setlinebuf(stdout);
if (read_environment()) {
fprintf(stderr, "Failed to read environment: %s\n", strerror(errno));
exit(1);
}
tmp = getenv("agi_enhanced");
if (tmp) {
if (sscanf(tmp, "%d.%d", &ver, &subver) != 2)
ver = 0;
}
if (ver < 1) {
fprintf(stderr, "No enhanced AGI services available. Use EAGI, not AGI\n");
exit(1);
}
if (run_script())
return -1;
exit(0);
}

View File

@@ -1,94 +0,0 @@
#!/usr/bin/perl
use strict;
use Socket;
use Carp;
use IO::Handle;
my $port = 4573;
$|=1;
# Setup some variables
my %AGI; my $tests = 0; my $fail = 0; my $pass = 0;
sub checkresult {
my ($res) = @_;
my $retval;
$tests++;
chomp $res;
if ($res =~ /^200/) {
$res =~ /result=(-?\d+)/;
if (!length($1)) {
print STDERR "FAIL ($res)\n";
$fail++;
} else {
print STDERR "PASS ($1)\n";
$pass++;
}
} else {
print STDERR "FAIL (unexpected result '$res')\n";
$fail++;
}
}
socket(SERVER, PF_INET, SOCK_STREAM, 0);
setsockopt(SERVER, SOL_SOCKET, SO_REUSEADDR, pack("l", 1));
bind(SERVER, sockaddr_in($port, INADDR_ANY)) || die("can't bind\n");
listen(SERVER, SOMAXCONN);
for(;;) {
my $raddr = accept(CLIENT, SERVER);
my ($s, $p) = sockaddr_in($raddr);
CLIENT->autoflush(1);
while(<CLIENT>) {
chomp;
last unless length($_);
if (/^agi_(\w+)\:\s+(.*)$/) {
$AGI{$1} = $2;
}
}
print STDERR "AGI Environment Dump from $s:$p --\n";
foreach my $i (sort keys %AGI) {
print STDERR " -- $i = $AGI{$i}\n";
}
print STDERR "1. Testing 'sendfile'...";
print CLIENT "STREAM FILE beep \"\"\n";
my $result = <CLIENT>;
&checkresult($result);
print STDERR "2. Testing 'sendtext'...";
print CLIENT "SEND TEXT \"hello world\"\n";
my $result = <CLIENT>;
&checkresult($result);
print STDERR "3. Testing 'sendimage'...";
print CLIENT "SEND IMAGE asterisk-image\n";
my $result = <CLIENT>;
&checkresult($result);
print STDERR "4. Testing 'saynumber'...";
print CLIENT "SAY NUMBER 192837465 \"\"\n";
my $result = <CLIENT>;
&checkresult($result);
print STDERR "5. Testing 'waitdtmf'...";
print CLIENT "WAIT FOR DIGIT 1000\n";
my $result = <CLIENT>;
&checkresult($result);
print STDERR "6. Testing 'record'...";
print CLIENT "RECORD FILE testagi gsm 1234 3000\n";
my $result = <CLIENT>;
&checkresult($result);
print STDERR "6a. Testing 'record' playback...";
print CLIENT "STREAM FILE testagi \"\"\n";
my $result = <CLIENT>;
&checkresult($result);
close(CLIENT);
print STDERR "================== Complete ======================\n";
print STDERR "$tests tests completed, $pass passed, $fail failed\n";
print STDERR "==================================================\n";
}

View File

@@ -1,44 +0,0 @@
#!/usr/bin/perl
#
# Build a database linking filenames to their numerical representations
# using a keypad for the DialAnMp3 application
#
$mp3dir="/usr/media/mpeg3";
dbmopen(%DIGITS, "/var/lib/asterisk/mp3list", 0644) || die("Unable to open mp3list");;
sub process_dir {
my ($dir) = @_;
my $file;
my $digits;
my @entries;
opendir(DIR, $dir);
@entries = readdir(DIR);
closedir(DIR);
foreach $_ (@entries) {
if (!/^\./) {
$file = "$dir/$_";
if (-d "$file") {
process_dir("$file");
} else {
$digits = $_;
$digits =~ s/[^ \w]+//g;
$digits =~ s/\_/ /g;
$digits =~ tr/[a-z]/[A-Z]/;
$digits =~ tr/[A-C]/2/;
$digits =~ tr/[D-F]/3/;
$digits =~ tr/[G-I]/4/;
$digits =~ tr/[J-L]/5/;
$digits =~ tr/[M-O]/6/;
$digits =~ tr/[P-S]/7/;
$digits =~ tr/[T-V]/8/;
$digits =~ tr/[W-Z]/9/;
$digits =~ s/\s+/ /;
print "File: $file, digits: $digits\n";
$DIGITS{$file} = $digits;
}
}
}
}
process_dir($mp3dir);

85
alaw.c
View File

@@ -1,85 +0,0 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* u-Law to Signed linear conversion
*
* Copyright (C) 1999, Mark Spencer
*
* Mark Spencer <markster@linux-support.net>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*/
#include <asterisk/alaw.h>
#define AMI_MASK 0x55
static inline unsigned char linear2alaw (short int linear)
{
int mask;
int seg;
int pcm_val;
static int seg_end[8] =
{
0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF
};
pcm_val = linear;
if (pcm_val >= 0)
{
/* Sign (7th) bit = 1 */
mask = AMI_MASK | 0x80;
}
else
{
/* Sign bit = 0 */
mask = AMI_MASK;
pcm_val = -pcm_val;
}
/* Convert the scaled magnitude to segment number. */
for (seg = 0; seg < 8; seg++)
{
if (pcm_val <= seg_end[seg])
break;
}
/* Combine the sign, segment, and quantization bits. */
return ((seg << 4) | ((pcm_val >> ((seg) ? (seg + 3) : 4)) & 0x0F)) ^ mask;
}
/*- End of function --------------------------------------------------------*/
static inline short int alaw2linear (unsigned char alaw)
{
int i;
int seg;
alaw ^= AMI_MASK;
i = ((alaw & 0x0F) << 4);
seg = (((int) alaw & 0x70) >> 4);
if (seg)
i = (i + 0x100) << (seg - 1);
return (short int) ((alaw & 0x80) ? i : -i);
}
unsigned char __ast_lin2a[8192];
short __ast_alaw[256];
void ast_alaw_init(void)
{
int i;
/*
* Set up mu-law conversion table
*/
for(i = 0;i < 256;i++)
{
__ast_alaw[i] = alaw2linear(i);
}
/* set up the reverse (mu-law) conversion table */
for(i = -32768; i < 32768; i++)
{
__ast_lin2a[((unsigned short)i) >> 3] = linear2alaw(i);
}
}

1011
app.c

File diff suppressed because it is too large Load Diff

View File

@@ -11,94 +11,17 @@
# the GNU General Public License
#
USE_MYSQL_VM_INTERFACE=0
USE_POSTGRES_VM_INTERFACE=0
APPS=app_dial.so app_playback.so app_voicemail.so app_directory.so app_intercom.so app_mp3.so app_system.so app_echo.so
#APPS=app_dial.so app_playback.so app_directory.so app_intercom.so app_mp3.so
APPS=app_dial.so app_playback.so app_voicemail.so app_directory.so app_mp3.so\
app_system.so app_echo.so app_record.so app_image.so app_url.so app_disa.so \
app_qcall.so app_adsiprog.so app_getcpeid.so app_milliwatt.so \
app_zapateller.so app_setcallerid.so app_festival.so \
app_queue.so app_senddtmf.so app_parkandannounce.so app_striplsd.so \
app_setcidname.so app_lookupcidname.so app_substring.so app_macro.so \
app_authenticate.so app_softhangup.so app_lookupblacklist.so \
app_waitforring.so app_privacy.so app_db.so app_chanisavail.so \
app_enumlookup.so app_transfer.so app_setcidnum.so app_cdr.so \
app_hasnewvoicemail.so app_sayunixtime.so app_cut.so app_read.so \
app_setcdruserfield.so app_random.so app_ices.so app_eval.so \
app_nbscat.so app_sendtext.so app_exec.so app_sms.so \
app_groupcount.so app_txtcidname.so app_controlplayback.so \
app_talkdetect.so app_alarmreceiver.so app_userevent.so app_verbose.so \
app_test.so app_forkcdr.so
ifneq (${OSARCH},Darwin)
APPS+=app_intercom.so
endif
#APPS+=app_sql_postgres.so
#APPS+=app_sql_odbc.so
#APPS+=app_rpt.so
APPS+=$(shell if [ -f /usr/include/linux/zaptel.h ]; then echo "app_zapras.so app_meetme.so app_flash.so app_zapbarge.so app_zapscan.so" ; fi)
APPS+=$(shell if [ -f /usr/local/include/zaptel.h ]; then echo "app_zapras.so app_meetme.so app_flash.so app_zapbarge.so app_zapscan.so" ; fi)
APPS+=$(shell if [ -f /usr/include/osp/osp.h ]; then echo "app_osplookup.so" ; fi)
CFLAGS+=-fPIC
ifeq ($(USE_POSTGRES_VM_INTERFACE),1)
CFLAGS+=-DUSEPOSTGRESVM
endif
ifeq ($(USE_MYSQL_VM_INTERFACE),1)
CFLAGS+=-DUSEMYSQLVM
endif
CFLAGS+=
all: $(APPS)
clean:
rm -f *.so *.o look .depend
rm -f *.so *.o
%.so : %.o
$(CC) $(SOLINK) -o $@ $<
app_rpt.so : app_rpt.o
$(CC) $(SOLINK) -o $@ $< -ltonezone
$(CC) -shared -Xlinker -x -o $@ $<
install: all
for x in $(APPS); do $(INSTALL) -m 755 $$x $(DESTDIR)$(MODULES_DIR) ; done
rm -f $(DESTDIR)$(MODULES_DIR)/app_datetime.so
app_voicemail.so : app_voicemail.o
ifeq ($(USE_MYSQL_VM_INTERFACE),1)
$(CC) $(SOLINK) -o $@ $(MLFLAGS) $< -L/usr/lib/mysql -lmysqlclient -lz
else
ifeq ($(USE_POSTGRES_VM_INTERFACE),1)
$(CC) $(SOLINK) -o $@ $(MLFLAGS) $< -lpq
else
$(CC) $(SOLINK) -o $@ $(MLFLAGS) $<
endif
endif
app_sql_postgres.o: app_sql_postgres.c
$(CC) -pipe -I/usr/local/pgsql/include $(CFLAGS) -c -o app_sql_postgres.o app_sql_postgres.c
app_sql_postgres.so: app_sql_postgres.o
$(CC) $(SOLINK) -o $@ $< -L/usr/local/pgsql/lib -lpq
app_sql_odbc.so: app_sql_odbc.o
$(CC) $(SOLINK) -o $@ $< -lodbc
look: look.c
$(CC) -pipe -O6 -g look.c -o look -lncurses
ifneq ($(wildcard .depend),)
include .depend
endif
depend: .depend
.depend:
../mkdep $(CFLAGS) `ls *.c`
env:
env
for x in $(APPS); do $(INSTALL) -m 755 $$x $(MODULES_DIR) ; done

File diff suppressed because it is too large Load Diff

View File

@@ -1,858 +0,0 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* Central Station Alarm receiver for Ademco Contact ID
*
* Copyright (C) 2004 Steve Rodgers
*
* Steve Rodgers <hwstar@rodgers.sdcoxmail.com>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*
* *** WARNING *** WARNING *** WARNING *** WARNING *** WARNING *** WARNING *** WARNING *** WARNING ***
*
* Use at your own risk. Please consult the GNU GPL license document included with Asterisk details. *
*
* *** WARNING *** WARNING *** WARNING *** WARNING *** WARNING *** WARNING *** WARNING *** WARNING ***
*
*/
#include <asterisk/lock.h>
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <asterisk/pbx.h>
#include <asterisk/module.h>
#include <asterisk/translate.h>
#include <asterisk/ulaw.h>
#include <asterisk/options.h>
#include <asterisk/app.h>
#include <asterisk/dsp.h>
#include <asterisk/config.h>
#include <asterisk/localtime.h>
#include <asterisk/callerid.h>
#include <asterisk/astdb.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/time.h>
#define ALMRCV_CONFIG "alarmreceiver.conf"
#define ADEMCO_CONTACT_ID "ADEMCO_CONTACT_ID"
struct event_node{
char data[17];
struct event_node *next;
};
typedef struct event_node event_node_t;
static char *tdesc = "Alarm Receiver for Asterisk";
static char *app = "AlarmReceiver";
static char *synopsis = "Provide support for receving alarm reports from a burglar or fire alarm panel";
static char *descrip =
"Alarm receiver application for Asterisk. Only 1 signalling format is supported at this time:\n"
"Ademco Contact ID. This application should be called whenever there is an alarm panel calling in\n"
"to dump its events. The application will handshake with the alarm panel, and receive events,\n"
"validate them, handshake them, and store them until the panel hangs up. Once the panel hangs up,\n"
"the application will run the command line specified by the eventcmd setting in alarmreceiver.conf\n"
"and pipe the events to the standard input of the application. Alarmreceiver.conf also contains settings\n"
"for DTMF timing, and for the loudness of the acknowledgement tones.\n";
/* Config Variables */
static int fdtimeout = 2000;
static int sdtimeout = 200;
static int toneloudness = 4096;
static int log_individual_events = 0;
static char event_spool_dir[128] = {'\0'};
static char event_app[128] = {'\0'};
static char db_family[128] = {'\0'};
static char time_stamp_format[128] = {"%a %b %d, %Y @ %H:%M:%S %Z"};
/* Misc variables */
static char event_file[14] = "/event-XXXXXX";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
/*
* Attempt to access a database variable and increment it,
* provided that the user defined db-family in alarmreceiver.conf
* The alarmreceiver app will write statistics to a few variables
* in this family if it is defined. If the new key doesn't exist in the
* family, then create it and set its value to 1.
*/
static void database_increment( char *key )
{
int res = 0;
unsigned v;
char value[16];
if(!strlen(db_family))
return; /* If not defined, don't do anything */
res = ast_db_get(db_family, key, value, sizeof(value) - 1);
if(res){
if(option_verbose >= 4)
ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: Creating database entry %s and setting to 1\n", key);
/* Guess we have to create it */
res = ast_db_put(db_family, key, "1");
return;
}
sscanf(value, "%u", &v);
v++;
if(option_verbose >= 4)
ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: New value for %s: %u\n", key, v);
snprintf(value, sizeof(value), "%u", v);
res = ast_db_put(db_family, key, value);
if((res)&&(option_verbose >= 4))
ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: database_increment write error");
return;
}
/*
* Build a MuLaw data block for a single frequency tone
*/
static void make_tone_burst(unsigned char *data, float freq, float loudness, int len, int *x)
{
int i;
float val;
for(i = 0; i < len; i++){
val = loudness * sin((freq * 2.0 * M_PI * (*x)++)/8000.0);
data[i] = AST_LIN2MU((int)val);
}
/* wrap back around from 8000 */
if (*x >= 8000) *x = 0;
return;
}
/*
* Send a single tone burst for a specifed duration and frequency.
* Returns 0 if successful
*/
static int send_tone_burst(struct ast_channel *chan, float freq, int duration, int tldn)
{
int res = 0;
int i = 0;
int x = 0;
struct ast_frame *f, wf;
struct {
unsigned char offset[AST_FRIENDLY_OFFSET];
unsigned char buf[640];
} tone_block;
for(;;)
{
if (ast_waitfor(chan, -1) < 0){
res = -1;
break;
}
f = ast_read(chan);
if (!f){
res = -1;
break;
}
if (f->frametype == AST_FRAME_VOICE) {
wf.frametype = AST_FRAME_VOICE;
wf.subclass = AST_FORMAT_ULAW;
wf.offset = AST_FRIENDLY_OFFSET;
wf.mallocd = 0;
wf.data = tone_block.buf;
wf.datalen = f->datalen;
wf.samples = wf.datalen;
make_tone_burst(tone_block.buf, freq, (float) tldn, wf.datalen, &x);
i += wf.datalen / 8;
if (i > duration) {
break;
}
if (ast_write(chan, &wf)){
if(option_verbose >= 4)
ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: Failed to write frame on %s\n", chan->name);
ast_log(LOG_WARNING, "AlarmReceiver Failed to write frame on %s\n",chan->name);
res = -1;
break;
}
}
ast_frfree(f);
}
return res;
}
/*
* Return the difference in milliseconds between two timeval structs
*/
static int ms_diff(struct timeval *tv1, struct timeval *tv2){
int ms;
ms = (tv1->tv_sec - tv2->tv_sec) * 1000;
ms += (tv1->tv_usec - tv2->tv_usec) / 1000;
return(ms);
}
/*
* Receive a string of DTMF digits where the length of the digit string is known in advance. Do not give preferential
* treatment to any digit value, and allow separate time out values to be specified for the first digit and all subsequent
* digits.
*
* Returns 0 if all digits successfully received.
* Returns 1 if a digit time out occurred
* Returns -1 if the caller hung up or there was a channel error.
*
*/
static int receive_dtmf_digits(struct ast_channel *chan, char *digit_string, int length, int fdto, int sdto)
{
int res = 0;
int i = 0;
int r;
struct ast_frame *f;
struct timeval now, lastdigittime;
gettimeofday(&lastdigittime,NULL);
for(;;){
gettimeofday(&now,NULL);
/* if outa time, leave */
if (ms_diff(&now,&lastdigittime) >
((i > 0) ? sdto : fdto)){
if(option_verbose >= 4)
ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: DTMF Digit Timeout on %s\n", chan->name);
ast_log(LOG_DEBUG,"AlarmReceiver: DTMF timeout on chan %s\n",chan->name);
res = 1;
break;
}
if ((r = ast_waitfor(chan, -1) < 0)) {
ast_log(LOG_DEBUG, "Waitfor returned %d\n", r);
continue;
}
f = ast_read(chan);
if (f == NULL){
res = -1;
break;
}
/* If they hung up, leave */
if ((f->frametype == AST_FRAME_CONTROL) &&
(f->subclass == AST_CONTROL_HANGUP)){
ast_frfree(f);
res = -1;
break;
}
/* if not DTMF, just do it again */
if (f->frametype != AST_FRAME_DTMF){
ast_frfree(f);
continue;
}
digit_string[i++] = f->subclass; /* save digit */
ast_frfree(f);
/* If we have all the digits we expect, leave */
if(i >= length)
break;
gettimeofday(&lastdigittime,NULL);
}
digit_string[i] = '\0'; /* Nul terminate the end of the digit string */
return res;
}
/*
* Write the metadata to the log file
*/
static int write_metadata( FILE *logfile, char *signalling_type, struct ast_channel *chan)
{
int res = 0;
time_t t;
struct tm now;
char *cl,*cn;
char workstring[80];
char timestamp[80];
/* Extract the caller ID location */
strncpy(workstring, chan->callerid, sizeof(workstring) - 1);
workstring[sizeof(workstring) - 1] = '\0';
ast_callerid_parse(workstring, &cn, &cl);
if (cl)
ast_shrink_phone_number(cl);
/* Get the current time */
time(&t);
ast_localtime(&t, &now, NULL);
/* Format the time */
strftime(timestamp, sizeof(timestamp), time_stamp_format, &now);
res = fprintf(logfile, "\n\n[metadata]\n\n");
if(res >= 0)
res = fprintf(logfile, "PROTOCOL=%s\n", signalling_type);
if(res >= 0)
res = fprintf(logfile, "CALLINGFROM=%s\n", (!cl) ? "<unknown>" : cl);
if(res >- 0)
res = fprintf(logfile, "CALLERNAME=%s\n", (!cn) ? "<unknown>" : cn);
if(res >= 0)
res = fprintf(logfile, "TIMESTAMP=%s\n\n", timestamp);
if(res >= 0)
res = fprintf(logfile, "[events]\n\n");
if(res < 0){
ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: can't write metadata\n");
ast_log(LOG_DEBUG,"AlarmReceiver: can't write metadata\n");
}
else
res = 0;
return res;
}
/*
* Write a single event to the log file
*/
static int write_event( FILE *logfile, event_node_t *event)
{
int res = 0;
if( fprintf(logfile, "%s\n", event->data) < 0)
res = -1;
return res;
}
/*
* If we are configured to log events, do so here.
*
*/
static int log_events(struct ast_channel *chan, char *signalling_type, event_node_t *event)
{
int res = 0;
char workstring[sizeof(event_spool_dir)+sizeof(event_file)] = "";
int fd;
FILE *logfile;
event_node_t *elp = event;
if(strlen(event_spool_dir)){
/* Make a template */
strncpy(workstring, event_spool_dir, sizeof(workstring) - 1);
strncat(workstring, event_file, sizeof(workstring) - strlen(workstring) - 1);
/* Make the temporary file */
fd = mkstemp(workstring);
if(fd == -1){
ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: can't make temporary file\n");
ast_log(LOG_DEBUG,"AlarmReceiver: can't make temporary file\n");
res = -1;
}
if(!res){
logfile = fdopen(fd, "w");
if(logfile){
/* Write the file */
res = write_metadata(logfile, signalling_type, chan);
if(!res)
while((!res) && (elp != NULL)){
res = write_event(logfile, elp);
elp = elp->next;
}
if(!res){
if(fflush(logfile) == EOF)
res = -1;
if(!res){
if(fclose(logfile) == EOF)
res = -1;
}
}
}
else
res = -1;
}
}
return res;
}
/*
* This function implements the logic to receive the Ademco contact ID format.
*
* The function will return 0 when the caller hangs up, else a -1 if there was a problem.
*/
static int receive_ademco_contact_id( struct ast_channel *chan, void *data, int fdto, int sdto, int tldn, event_node_t **ehead)
{
int i,j;
int res = 0;
int checksum;
char event[17];
event_node_t *enew, *elp;
int got_some_digits = 0;
int events_received = 0;
int ack_retries = 0;
static char digit_map[15] = "0123456789*#ABC";
static unsigned char digit_weights[15] = {10,1,2,3,4,5,6,7,8,9,11,12,13,14,15};
database_increment("calls-received");
/* Wait for first event */
if(option_verbose >= 4)
ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: Waiting for first event from panel\n");
while(res >= 0){
if(got_some_digits == 0){
/* Send ACK tone sequence */
if(option_verbose >= 4)
ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: Sending 1400Hz 100ms burst (ACK)\n");
res = send_tone_burst(chan, 1400.0, 100, tldn);
if(!res)
res = ast_safe_sleep(chan, 100);
if(!res){
if(option_verbose >= 4)
ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: Sending 2300Hz 100ms burst (ACK)\n");
res = send_tone_burst(chan, 2300.0, 100, tldn);
}
}
if( res >= 0)
res = receive_dtmf_digits(chan, event, sizeof(event) - 1, fdto, sdto);
if (res < 0){
if(events_received == 0)
/* Hangup with no events received should be logged in the DB */
database_increment("no-events-received");
else{
if(ack_retries){
if(option_verbose >= 4)
ast_verbose(VERBOSE_PREFIX_2 "AlarmReceiver: ACK retries during this call: %d\n", ack_retries);
database_increment("ack-retries");
}
}
if(option_verbose >= 4)
ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: App exiting...\n");
res = -1;
break;
}
if(res != 0){
/* Didn't get all of the digits */
if(option_verbose >= 2)
ast_verbose(VERBOSE_PREFIX_2 "AlarmReceiver: Incomplete string: %s, trying again...\n", event);
if(!got_some_digits){
got_some_digits = (strlen(event)) ? 1 : 0;
ack_retries++;
}
continue;
}
got_some_digits = 1;
if(option_verbose >= 2)
ast_verbose(VERBOSE_PREFIX_2 "AlarmReceiver: Received Event %s\n", event);
ast_log(LOG_DEBUG, "AlarmReceiver: Received event: %s\n", event);
/* Calculate checksum */
for(j = 0, checksum = 0; j < 16; j++){
for(i = 0 ; i < sizeof(digit_map) ; i++){
if(digit_map[i] == event[j])
break;
}
if(i == 16)
break;
checksum += digit_weights[i];
}
if(i == 16){
if(option_verbose >= 2)
ast_verbose(VERBOSE_PREFIX_2 "AlarmReceiver: Bad DTMF character %c, trying again\n", event[j]);
continue; /* Bad character */
}
/* Checksum is mod(15) of the total */
checksum = checksum % 15;
if(checksum){
database_increment("checksum-errors");
if(option_verbose >= 2){
ast_verbose(VERBOSE_PREFIX_2 "AlarmReceiver: Nonzero checksum\n");
ast_log(LOG_DEBUG, "AlarmReceiver: Nonzero checksum\n");
continue;
}
}
/* Check the message type for correctness */
if(strncmp(event + 4, "18", 2)){
if(strncmp(event + 4, "98", 2)){
database_increment("format-errors");
if(option_verbose >= 2)
ast_verbose(VERBOSE_PREFIX_2 "AlarmReceiver: Wrong message type\n");
ast_log(LOG_DEBUG, "AlarmReceiver: Wrong message type\n");
continue;
}
}
events_received++;
/* Queue the Event */
if((enew = malloc(sizeof(event_node_t))) == NULL){
if(option_verbose >= 1)
ast_verbose(VERBOSE_PREFIX_1 "AlarmReceiver: Failed to allocate memory\n");
ast_log(LOG_WARNING, "AlarmReceiver Failed to allocate memory\n");
res = -1;
break;
}
memset(enew, 0, sizeof(event_node_t));
enew->next = NULL;
strncpy(enew->data, event, sizeof(enew->data) - 1);
/*
* Insert event onto end of list
*/
if(*ehead == NULL){
*ehead = enew;
}
else{
for(elp = *ehead; elp->next != NULL; elp = elp->next)
;
elp->next = enew;
}
if(res > 0)
res = 0;
/* Let the user have the option of logging the single event before sending the kissoff tone */
if((res == 0) && (log_individual_events))
res = log_events(chan, ADEMCO_CONTACT_ID, enew);
/* Wait 200 msec before sending kissoff */
if(res == 0)
res = ast_safe_sleep(chan, 200);
/* Send the kissoff tone */
if(res == 0)
res = send_tone_burst(chan, 1400.0, 900, tldn);
}
return res;
}
/*
* This is the main function called by Asterisk Core whenever the App is invoked in the extension logic.
* This function will always return 0.
*/
static int alarmreceiver_exec(struct ast_channel *chan, void *data)
{
int res = 0;
struct localuser *u;
event_node_t *elp, *efree;
char signalling_type[64] = "";
event_node_t *event_head = NULL;
LOCAL_USER_ADD(u);
/* Set write and read formats to ULAW */
if(option_verbose >= 4)
ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: Setting read and write formats to ULAW\n");
if (ast_set_write_format(chan,AST_FORMAT_ULAW)){
ast_log(LOG_WARNING, "AlarmReceiver: Unable to set write format to Mu-law on %s\n",chan->name);
return -1;
}
if (ast_set_read_format(chan,AST_FORMAT_ULAW)){
ast_log(LOG_WARNING, "AlarmReceiver: Unable to set read format to Mu-law on %s\n",chan->name);
return -1;
}
/* Set default values for this invokation of the application */
strncpy(signalling_type, ADEMCO_CONTACT_ID, sizeof(signalling_type) - 1);
/* Answer the channel if it is not already */
if(option_verbose >= 4)
ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: Answering channel\n");
if (chan->_state != AST_STATE_UP) {
res = ast_answer(chan);
if (res) {
LOCAL_USER_REMOVE(u);
return -1;
}
}
/* Wait for the connection to settle post-answer */
if(option_verbose >= 4)
ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: Waiting for connection to stabilize\n");
res = ast_safe_sleep(chan, 1250);
/* Attempt to receive the events */
if(!res){
/* Determine the protocol to receive in advance */
/* Note: Ademco contact is the only one supported at this time */
/* Others may be added later */
if(!strcmp(signalling_type, ADEMCO_CONTACT_ID))
receive_ademco_contact_id(chan, data, fdtimeout, sdtimeout, toneloudness, &event_head);
else
res = -1;
}
/* Events queued by receiver, write them all out here if so configured */
if((!res) && (log_individual_events == 0)){
res = log_events(chan, signalling_type, event_head);
}
/*
* Do we exec a command line at the end?
*/
if((!res) && (strlen(event_app)) && (event_head)){
ast_log(LOG_DEBUG,"Alarmreceiver: executing: %s\n", event_app);
ast_safe_system(event_app);
}
/*
* Free up the data allocated in our linked list
*/
for(elp = event_head; (elp != NULL);){
efree = elp;
elp = elp->next;
free(efree);
}
LOCAL_USER_REMOVE(u);
return 0;
}
/*
* Load the configuration from the configuration file
*/
static int load_config(void)
{
struct ast_config *cfg;
char *p;
/* Read in the config file */
cfg = ast_load(ALMRCV_CONFIG);
if(!cfg){
if(option_verbose >= 4)
ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: No config file\n");
}
else{
p = ast_variable_retrieve(cfg, "general", "eventcmd");
if(p){
strncpy(event_app, p, sizeof(event_app) - 1);
event_app[sizeof(event_app) - 1] = '\0';
}
p = ast_variable_retrieve(cfg, "general", "loudness");
if(p){
toneloudness = atoi(p);
if(toneloudness < 100)
toneloudness = 100;
if(toneloudness > 8192)
toneloudness = 8192;
}
p = ast_variable_retrieve(cfg, "general", "fdtimeout");
if(p){
fdtimeout = atoi(p);
if(fdtimeout < 1000)
fdtimeout = 1000;
if(fdtimeout > 10000)
fdtimeout = 10000;
}
p = ast_variable_retrieve(cfg, "general", "sdtimeout");
if(p){
sdtimeout = atoi(p);
if(sdtimeout < 110)
sdtimeout = 110;
if(sdtimeout > 4000)
sdtimeout = 4000;
}
p = ast_variable_retrieve(cfg, "general", "logindividualevents");
if(p){
log_individual_events = ast_true(p);
}
p = ast_variable_retrieve(cfg, "general", "eventspooldir");
if(p){
strncpy(event_spool_dir, p, sizeof(event_spool_dir) - 1);
event_spool_dir[sizeof(event_spool_dir) - 1] = '\0';
}
p = ast_variable_retrieve(cfg, "general", "timestampformat");
if(p){
strncpy(time_stamp_format, p, sizeof(time_stamp_format) - 1);
time_stamp_format[sizeof(time_stamp_format) - 1] = '\0';
}
p = ast_variable_retrieve(cfg, "general", "db-family");
if(p){
strncpy(db_family, p, sizeof(db_family) - 1);
db_family[sizeof(db_family) - 1] = '\0';
}
ast_destroy(cfg);
}
return 0;
}
/*
* These functions are required to implement an Asterisk App.
*/
int unload_module(void)
{
STANDARD_HANGUP_LOCALUSERS;
return ast_unregister_application(app);
}
int load_module(void)
{
load_config();
return ast_register_application(app, alarmreceiver_exec, synopsis, descrip);
}
char *description(void)
{
return tdesc;
}
int usecount(void)
{
int res;
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -1,172 +0,0 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* Execute arbitrary authenticate commands
*
* Copyright (C) 1999, Mark Spencer
*
* Mark Spencer <markster@linux-support.net>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*/
#include <asterisk/lock.h>
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <asterisk/pbx.h>
#include <asterisk/module.h>
#include <asterisk/app.h>
#include <asterisk/astdb.h>
#include <asterisk/utils.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
static char *tdesc = "Authentication Application";
static char *app = "Authenticate";
static char *synopsis = "Authenticate a user";
static char *descrip =
" Authenticate(password[|options]): Requires a user to enter a"
"given password in order to continue execution. If the\n"
"password begins with the '/' character, it is interpreted as\n"
"a file which contains a list of valid passwords (1 per line).\n"
"an optional set of opions may be provided by concatenating any\n"
"of the following letters:\n"
" a - Set account code to the password that is entered\n"
" d - Interpret path as database key, not literal file\n"
" r - Remove database key upon successful entry (valid with 'd' only)\n"
"\n"
"When using a database key, the value associated with the key can be\n"
"anything.\n"
"Returns 0 if the user enters a valid password within three\n"
"tries, or -1 otherwise (or on hangup).\n";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
static int auth_exec(struct ast_channel *chan, void *data)
{
int res=0;
int retries;
struct localuser *u;
char password[256]="";
char passwd[256];
char *opts;
char *prompt;
if (!data || ast_strlen_zero(data)) {
ast_log(LOG_WARNING, "Authenticate requires an argument(password)\n");
return -1;
}
LOCAL_USER_ADD(u);
if (chan->_state != AST_STATE_UP) {
res = ast_answer(chan);
if (res) {
LOCAL_USER_REMOVE(u);
return -1;
}
}
strncpy(password, data, sizeof(password) - 1);
opts=strchr(password, '|');
if (opts) {
*opts = 0;
opts++;
} else
opts = "";
/* Start asking for password */
prompt = "agent-pass";
for (retries = 0; retries < 3; retries++) {
res = ast_app_getdata(chan, prompt, passwd, sizeof(passwd) - 2, 0);
if (res < 0)
break;
res = 0;
if (password[0] == '/') {
if (strchr(opts, 'd')) {
char tmp[256];
/* Compare against a database key */
if (!ast_db_get(password + 1, passwd, tmp, sizeof(tmp))) {
/* It's a good password */
if (strchr(opts, 'r')) {
ast_db_del(password + 1, passwd);
}
break;
}
} else {
/* Compare against a file */
FILE *f;
f = fopen(password, "r");
if (f) {
char buf[256] = "";
while(!feof(f)) {
fgets(buf, sizeof(buf), f);
if (!feof(f) && !ast_strlen_zero(buf)) {
buf[strlen(buf) - 1] = '\0';
if (!ast_strlen_zero(buf) && !strcmp(passwd, buf))
break;
}
}
fclose(f);
if (!ast_strlen_zero(buf) && !strcmp(passwd, buf))
break;
} else
ast_log(LOG_WARNING, "Unable to open file '%s' for authentication: %s\n", password, strerror(errno));
}
} else {
/* Compare against a fixed password */
if (!strcmp(passwd, password))
break;
}
prompt="auth-incorrect";
}
if ((retries < 3) && !res) {
if (strchr(opts, 'a'))
ast_cdr_setaccount(chan, passwd);
res = ast_streamfile(chan, "auth-thankyou", chan->language);
if (!res)
res = ast_waitstream(chan, "");
} else {
if (!res)
res = ast_streamfile(chan, "vm-goodbye", chan->language);
if (!res)
res = ast_waitstream(chan, "");
res = -1;
}
LOCAL_USER_REMOVE(u);
return res;
}
int unload_module(void)
{
STANDARD_HANGUP_LOCALUSERS;
return ast_unregister_application(app);
}
int load_module(void)
{
return ast_register_application(app, auth_exec, synopsis, descrip);
}
char *description(void)
{
return tdesc;
}
int usecount(void)
{
int res;
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -1,66 +0,0 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* Applictions connected with CDR engine
*
* Copyright (C) 2003, Digium
*
* Martin Pycko <martinp@digium.com>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*/
#include <sys/types.h>
#include <asterisk/channel.h>
#include <asterisk/module.h>
#include <asterisk/pbx.h>
#include <stdlib.h>
static char *tdesc = "Make sure asterisk doesn't save CDR for a certain call";
static char *nocdr_descrip = "NoCDR(): makes sure there won't be any CDR written for a certain call";
static char *nocdr_app = "NoCDR";
static char *nocdr_synopsis = "Make sure asterisk doesn't save CDR for a certain call";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
static int nocdr_exec(struct ast_channel *chan, void *data)
{
if (chan->cdr) {
ast_cdr_free(chan->cdr);
chan->cdr = NULL;
}
return 0;
}
int unload_module(void)
{
STANDARD_HANGUP_LOCALUSERS;
return ast_unregister_application(nocdr_app);
}
int load_module(void)
{
return ast_register_application(nocdr_app, nocdr_exec, nocdr_synopsis, nocdr_descrip);
}
char *description(void)
{
return tdesc;
}
int usecount(void)
{
int res;
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -1,137 +0,0 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* Check if Channel is Available
*
* Copyright (C) 2003, Digium
*
* Mark Spencer <markster@digium.com>
* James Golovich <james@gnuinter.net>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*
*/
#include <asterisk/lock.h>
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <asterisk/pbx.h>
#include <asterisk/module.h>
#include <asterisk/app.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <sys/ioctl.h>
static char *tdesc = "Check if channel is available";
static char *app = "ChanIsAvail";
static char *synopsis = "Check if channel is available";
static char *descrip =
" ChanIsAvail(Technology/resource[&Technology2/resource2...]): \n"
"Checks is any of the requested channels are available. If none\n"
"of the requested channels are available the new priority will be\n"
"n+101 (unless such a priority does not exist or on error, in which\n"
"case ChanIsAvail will return -1).\n"
"If any of the requested channels are available, the next priority will be n+1,\n"
"the channel variable ${AVAILCHAN} will be set to the name of the available channel\n"
"and the ChanIsAvail app will return 0.\n"
"${AVAILORIGCHAN} is the canonical channel name that was used to create the channel.\n"
"${AVAILSTATUS} is the status code for the channel.\n";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
static int chanavail_exec(struct ast_channel *chan, void *data)
{
int res=-1;
struct localuser *u;
char info[512], tmp[512], *peers, *tech, *number, *rest, *cur;
struct ast_channel *tempchan;
if (!data) {
ast_log(LOG_WARNING, "ChanIsAvail requires an argument (Zap/1&Zap/2)\n");
return -1;
}
LOCAL_USER_ADD(u);
strncpy(info, (char *)data, sizeof(info)-1);
peers = info;
if (peers) {
cur = peers;
do {
/* remember where to start next time */
rest = strchr(cur, '&');
if (rest) {
*rest = 0;
rest++;
}
tech = cur;
number = strchr(tech, '/');
if (!number) {
ast_log(LOG_WARNING, "ChanIsAvail argument takes format ([technology]/[device])\n");
return -1;
}
*number = '\0';
number++;
if ((tempchan = ast_request(tech, chan->nativeformats, number))) {
pbx_builtin_setvar_helper(chan, "AVAILCHAN", tempchan->name);
/* Store the originally used channel too */
snprintf(tmp, sizeof(tmp), "%s/%s", tech, number);
pbx_builtin_setvar_helper(chan, "AVAILORIGCHAN", tmp);
ast_hangup(tempchan);
tempchan = NULL;
res = 1;
break;
}
cur = rest;
} while (cur);
}
if (res < 1) {
pbx_builtin_setvar_helper(chan, "AVAILCHAN", "");
pbx_builtin_setvar_helper(chan, "AVAILORIGCHAN", "");
if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 101, chan->callerid))
chan->priority+=100;
else
return -1;
}
LOCAL_USER_REMOVE(u);
return 0;
}
int unload_module(void)
{
STANDARD_HANGUP_LOCALUSERS;
return ast_unregister_application(app);
}
int load_module(void)
{
return ast_register_application(app, chanavail_exec, synopsis, descrip);
}
char *description(void)
{
return tdesc;
}
int usecount(void)
{
int res;
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -1,143 +0,0 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* Trivial application to control playback a sound file
*
* Copyright (C) 1999, Mark Spencer
*
* Mark Spencer <markster@linux-support.net>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*/
#include <asterisk/lock.h>
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <asterisk/pbx.h>
#include <asterisk/app.h>
#include <asterisk/module.h>
#include <asterisk/translate.h>
#include <asterisk/utils.h>
#include <string.h>
#include <stdlib.h>
static char *tdesc = "Control Playback Application";
static char *app = "ControlPlayback";
static char *synopsis = "Play a file with fast forward and rewind";
static char *descrip =
"ControlPlayback(filename[|skipms[|ffchar[|rewchar[|stopchar[|pausechr]]]]]):\n"
" Plays back a given filename (do not put extension). Options may also\n"
" be included following a pipe symbol. You can use * and # to rewind and\n"
" fast forward the playback specified. If 'stopchar' is added the file will\n"
" terminate playback when 'stopchar' is pressed. Returns -1 if the channel\n"
" was hung up, or if the file does not exist. Returns 0 otherwise.\n\n"
" Example: exten => 1234,1,ControlPlayback(file|4000|*|#|1|0)\n\n";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
static int is_on_phonepad(char key)
{
return (key == 35 || key == 42 || (key >= 48 && key <= 57)) ? 1 : 0;
}
static int controlplayback_exec(struct ast_channel *chan, void *data)
{
int res = 0;
int skipms = 0;
struct localuser *u;
char tmp[256];
char *skip = NULL, *fwd = NULL, *rev = NULL, *stop = NULL, *pause = NULL, *file = NULL;
if (!data || ast_strlen_zero((char *)data)) {
ast_log(LOG_WARNING, "ControlPlayback requires an argument (filename)\n");
return -1;
}
strncpy(tmp, (char *)data, sizeof(tmp)-1);
file = tmp;
if ((skip=strchr(tmp,'|'))) {
*skip = '\0';
*skip++;
fwd=strchr(skip,'|');
if (fwd) {
*fwd = '\0';
*fwd++;
rev = strchr(fwd,'|');
if (rev) {
*rev = '\0';
*rev++;
stop = strchr(rev,'|');
if (stop) {
*stop = '\0';
*stop++;
pause = strchr(stop,'|');
if (pause) {
*pause = '\0';
*pause++;
}
}
}
}
}
skipms = skip ? atoi(skip) : 3000;
if (!skipms)
skipms = 3000;
if (!fwd || !is_on_phonepad(*fwd))
fwd = "#";
if (!rev || !is_on_phonepad(*rev))
rev = "*";
if (stop && !is_on_phonepad(*stop))
stop = NULL;
if (pause && !is_on_phonepad(*pause))
pause = NULL;
LOCAL_USER_ADD(u);
res = ast_control_streamfile(chan, file, fwd, rev, stop, pause, skipms);
LOCAL_USER_REMOVE(u);
/* If we stopped on one of our stop keys, return 0 */
if(stop && strchr(stop, res))
res = 0;
return res;
}
int unload_module(void)
{
STANDARD_HANGUP_LOCALUSERS;
return ast_unregister_application(app);
}
int load_module(void)
{
return ast_register_application(app, controlplayback_exec, synopsis, descrip);
}
char *description(void)
{
return tdesc;
}
int usecount(void)
{
int res;
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -1,198 +0,0 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* Cut application
*
* Copyright (c) 2003 Tilghman Lesher. All rights reserved.
*
* Tilghman Lesher <app_cut__v003@the-tilghman.com>
*
* $Id$
*
* This code is released by the author with no restrictions on usage.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/options.h>
#include <asterisk/channel.h>
#include <asterisk/pbx.h>
#include <asterisk/module.h>
/* Maximum length of any variable */
#define MAXRESULT 1024
static char *tdesc = "Cuts up variables";
static char *app_cut = "Cut";
static char *cut_synopsis = "Cut(newvar=varname|delimiter|fieldspec)";
static char *cut_descrip =
"Cut(newvar=varname,delimiter,field)\n"
" newvar - new variable created from result string\n"
" varname - variable you want cut\n"
" delimiter - defaults to '-'\n"
" fieldspec - number of the field you want (1-based offset)\n"
" may also be specified as a range (with -)\n"
" or group of ranges and fields (with &)\n"
" Returns 0 or -1 on hangup or error.\n";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
static int cut_exec(struct ast_channel *chan, void *data)
{
int res=0;
struct localuser *u;
char *s, *newvar=NULL, *varname=NULL, *delimiter=NULL, *field=NULL;
int args_okay = 0;
LOCAL_USER_ADD(u);
/* Check and parse arguments */
if (data) {
s = ast_strdupa((char *)data);
if (s) {
newvar = strsep(&s, "=");
if (newvar && (newvar[0] != '\0')) {
varname = strsep(&s, "|");
if (varname && (varname[0] != '\0')) {
delimiter = strsep(&s, "|");
if (delimiter) {
field = strsep(&s, "|");
if (field) {
args_okay = 1;
}
}
}
}
} else {
ast_log(LOG_ERROR, "Out of memory\n");
res = -1;
}
}
if (args_okay) {
char d, ds[2];
char *tmp = alloca(strlen(varname) + 4);
char varvalue[MAXRESULT], *tmp2=varvalue;
char retstring[MAXRESULT];
memset(retstring, 0, MAXRESULT);
if (tmp) {
snprintf(tmp, strlen(varname) + 4, "${%s}", varname);
memset(varvalue, 0, sizeof(varvalue));
} else {
ast_log(LOG_ERROR, "Out of memory");
return -1;
}
if (delimiter[0])
d = delimiter[0];
else
d = '-';
/* String form of the delimiter, for use with strsep(3) */
snprintf(ds, sizeof(ds), "%c", d);
pbx_substitute_variables_helper(chan, tmp, tmp2, MAXRESULT - 1);
if (tmp2) {
int curfieldnum = 1;
while ((tmp2 != NULL) && (field != NULL)) {
char *nextgroup = strsep(&field, "&");
int num1 = 0, num2 = MAXRESULT;
char trashchar;
if (sscanf(nextgroup, "%d-%d", &num1, &num2) == 2) {
/* range with both start and end */
} else if (sscanf(nextgroup, "-%d", &num2) == 1) {
/* range with end */
num1 = 0;
} else if ((sscanf(nextgroup, "%d%c", &num1, &trashchar) == 2) && (trashchar == '-')) {
/* range with start */
num2 = MAXRESULT;
} else if (sscanf(nextgroup, "%d", &num1) == 1) {
/* single number */
num2 = num1;
} else {
ast_log(LOG_ERROR, "Cut(): Illegal range '%s'\n", nextgroup);
ast_log(LOG_ERROR, "Usage: %s\n", cut_synopsis);
return -1;
}
/* Get to start, if any */
if (num1 > 0) {
while ((tmp2 != (char *)NULL + 1) && (curfieldnum < num1)) {
tmp2 = index(tmp2, d) + 1;
curfieldnum++;
}
}
/* Most frequent problem is the expectation of reordering fields */
if ((num1 > 0) && (curfieldnum > num1)) {
ast_log(LOG_WARNING, "Cut(): we're already past the field you wanted?\n");
}
/* Re-null tmp2 if we added 1 to NULL */
if (tmp2 == (char *)NULL + 1)
tmp2 = NULL;
/* Output fields until we either run out of fields or num2 is reached */
while ((tmp2 != NULL) && (curfieldnum <= num2)) {
char *tmp3 = strsep(&tmp2, ds);
int curlen = strlen(retstring);
if (strlen(retstring)) {
snprintf(retstring + curlen, MAXRESULT - curlen, "%c%s", d, tmp3);
} else {
snprintf(retstring, MAXRESULT, "%s", tmp3);
}
curfieldnum++;
}
}
}
pbx_builtin_setvar_helper(chan, newvar, retstring);
}
LOCAL_USER_REMOVE(u);
return res;
}
int unload_module(void)
{
STANDARD_HANGUP_LOCALUSERS;
return ast_unregister_application(app_cut);
}
int load_module(void)
{
return ast_register_application(app_cut, cut_exec, cut_synopsis, cut_descrip);
}
char *description(void)
{
return tdesc;
}
int usecount(void)
{
int res;
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -1,81 +0,0 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* Time of day - Report the time of day
*
* Copyright (C) 1999, Mark Spencer
*
* Mark Spencer <markster@linux-support.net>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*/
#include <asterisk/lock.h>
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <asterisk/pbx.h>
#include <asterisk/module.h>
#include <asterisk/say.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
static char *tdesc = "Date and Time";
static char *app = "DateTime";
static char *synopsis = "Say the date and time";
static char *descrip =
" DateTime(): Says the current date and time. Returns -1 on hangup or 0\n"
"otherwise.\n";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
static int datetime_exec(struct ast_channel *chan, void *data)
{
int res=0;
time_t t;
struct localuser *u;
LOCAL_USER_ADD(u);
time(&t);
if (chan->_state != AST_STATE_UP)
res = ast_answer(chan);
if (!res)
res = ast_say_datetime(chan, t, "", chan->language);
LOCAL_USER_REMOVE(u);
return res;
}
int unload_module(void)
{
STANDARD_HANGUP_LOCALUSERS;
return ast_unregister_application(app);
}
int load_module(void)
{
return ast_register_application(app, datetime_exec, synopsis, descrip);
}
char *description(void)
{
return tdesc;
}
int usecount(void)
{
int res;
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -1,255 +0,0 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* Database access functions
*
* Copyright (C) 1999, Mark Spencer
* Copyright (C) 2003, Jefferson Noxon
*
* Mark Spencer <markster@linux-support.net>
* Jefferson Noxon <jeff@debian.org>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*/
#include <sys/types.h>
#include <asterisk/options.h>
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <asterisk/pbx.h>
#include <asterisk/module.h>
#include <asterisk/astdb.h>
#include <asterisk/lock.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
static char *tdesc = "Database access functions for Asterisk extension logic";
static char *g_descrip =
" DBget(varname=family/key): Retrieves a value from the Asterisk\n"
"database and stores it in the given variable. Always returns 0. If the\n"
"requested key is not found, jumps to priority n+101 if available.\n";
static char *p_descrip =
" DBput(family/key=value): Stores the given value in the Asterisk\n"
"database. Always returns 0.\n";
static char *d_descrip =
" DBdel(family/key): Deletes a key from the Asterisk database. Always\n"
"returns 0.\n";
static char *dt_descrip =
" DBdeltree(family[/keytree]): Deletes a family or keytree from the Asterisk\n"
"database. Always returns 0.\n";
static char *g_app = "DBget";
static char *p_app = "DBput";
static char *d_app = "DBdel";
static char *dt_app = "DBdeltree";
static char *g_synopsis = "Retrieve a value from the database";
static char *p_synopsis = "Store a value in the database";
static char *d_synopsis = "Delete a key from the database";
static char *dt_synopsis = "Delete a family or keytree from the database";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
static int deltree_exec (struct ast_channel *chan, void *data)
{
int arglen;
char *argv, *family, *keytree;
arglen = strlen (data);
argv = alloca (arglen + 1);
if (!argv) { /* Why would this fail? */
ast_log (LOG_DEBUG, "Memory allocation failed\n");
return 0;
}
memcpy (argv, data, arglen + 1);
if (strchr (argv, '/')) {
family = strsep (&argv, "/");
keytree = strsep (&argv, "\0");
if (!family || !keytree) {
ast_log (LOG_DEBUG, "Ignoring; Syntax error in argument\n");
return 0;
}
if (!strlen (keytree))
keytree = 0;
} else {
family = argv;
keytree = 0;
}
if (option_verbose > 2) {
if (keytree)
ast_verbose (VERBOSE_PREFIX_3 "DBdeltree: family=%s, keytree=%s\n", family, keytree);
else
ast_verbose (VERBOSE_PREFIX_3 "DBdeltree: family=%s\n", family);
}
if (ast_db_deltree (family, keytree)) {
if (option_verbose > 2)
ast_verbose (VERBOSE_PREFIX_3 "DBdeltree: Error deleting key from database.\n");
}
return 0;
}
static int del_exec (struct ast_channel *chan, void *data)
{
int arglen;
char *argv, *family, *key;
arglen = strlen (data);
argv = alloca (arglen + 1);
if (!argv) { /* Why would this fail? */
ast_log (LOG_DEBUG, "Memory allocation failed\n");
return 0;
}
memcpy (argv, data, arglen + 1);
if (strchr (argv, '/')) {
family = strsep (&argv, "/");
key = strsep (&argv, "\0");
if (!family || !key) {
ast_log (LOG_DEBUG, "Ignoring; Syntax error in argument\n");
return 0;
}
if (option_verbose > 2)
ast_verbose (VERBOSE_PREFIX_3 "DBdel: family=%s, key=%s\n", family, key);
if (ast_db_del (family, key)) {
if (option_verbose > 2)
ast_verbose (VERBOSE_PREFIX_3 "DBdel: Error deleting key from database.\n");
}
} else {
ast_log (LOG_DEBUG, "Ignoring, no parameters\n");
}
return 0;
}
static int put_exec (struct ast_channel *chan, void *data)
{
int arglen;
char *argv, *value, *family, *key;
arglen = strlen (data);
argv = alloca (arglen + 1);
if (!argv) { /* Why would this fail? */
ast_log (LOG_DEBUG, "Memory allocation failed\n");
return 0;
}
memcpy (argv, data, arglen + 1);
if (strchr (argv, '/') && strchr (argv, '=')) {
family = strsep (&argv, "/");
key = strsep (&argv, "=");
value = strsep (&argv, "\0");
if (!value || !family || !key) {
ast_log (LOG_DEBUG, "Ignoring; Syntax error in argument\n");
return 0;
}
if (option_verbose > 2)
ast_verbose (VERBOSE_PREFIX_3 "DBput: family=%s, key=%s, value=%s\n", family, key, value);
if (ast_db_put (family, key, value)) {
if (option_verbose > 2)
ast_verbose (VERBOSE_PREFIX_3 "DBput: Error writing value to database.\n");
}
} else {
ast_log (LOG_DEBUG, "Ignoring, no parameters\n");
}
return 0;
}
static int get_exec (struct ast_channel *chan, void *data)
{
int arglen;
char *argv, *varname, *family, *key;
char dbresult[256];
arglen = strlen (data);
argv = alloca (arglen + 1);
if (!argv) { /* Why would this fail? */
ast_log (LOG_DEBUG, "Memory allocation failed\n");
return 0;
}
memcpy (argv, data, arglen + 1);
if (strchr (argv, '=') && strchr (argv, '/')) {
varname = strsep (&argv, "=");
family = strsep (&argv, "/");
key = strsep (&argv, "\0");
if (!varname || !family || !key) {
ast_log (LOG_DEBUG, "Ignoring; Syntax error in argument\n");
return 0;
}
if (option_verbose > 2)
ast_verbose (VERBOSE_PREFIX_3 "DBget: varname=%s, family=%s, key=%s\n", varname, family, key);
if (!ast_db_get (family, key, dbresult, sizeof (dbresult) - 1)) {
pbx_builtin_setvar_helper (chan, varname, dbresult);
if (option_verbose > 2)
ast_verbose (VERBOSE_PREFIX_3 "DBget: set variable %s to %s\n", varname, dbresult);
} else {
if (option_verbose > 2)
ast_verbose (VERBOSE_PREFIX_3 "DBget: Value not found in database.\n");
/* Send the call to n+101 priority, where n is the current priority */
if (ast_exists_extension (chan, chan->context, chan->exten, chan->priority + 101, chan->callerid))
chan->priority += 100;
}
} else {
ast_log (LOG_DEBUG, "Ignoring, no parameters\n");
}
return 0;
}
int unload_module (void)
{
int retval;
STANDARD_HANGUP_LOCALUSERS;
retval = ast_unregister_application (dt_app);
retval |= ast_unregister_application (d_app);
retval |= ast_unregister_application (p_app);
retval |= ast_unregister_application (g_app);
return retval;
}
int load_module (void)
{
int retval;
retval = ast_register_application (g_app, get_exec, g_synopsis, g_descrip);
if (!retval)
retval = ast_register_application (p_app, put_exec, p_synopsis, p_descrip);
if (!retval)
retval = ast_register_application (d_app, del_exec, d_synopsis, d_descrip);
if (!retval)
retval = ast_register_application (dt_app, deltree_exec, dt_synopsis, dt_descrip);
return retval;
}
char *description (void)
{
return tdesc;
}
int usecount (void)
{
int res;
STANDARD_USECOUNT (res);
return res;
}
char *key ()
{
return ASTERISK_GPL_KEY;
}

File diff suppressed because it is too large Load Diff

View File

@@ -11,7 +11,6 @@
* the GNU General Public License
*/
#include <asterisk/lock.h>
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
@@ -19,29 +18,16 @@
#include <asterisk/module.h>
#include <asterisk/config.h>
#include <asterisk/say.h>
#include <asterisk/utils.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <pthread.h>
#include <stdio.h>
#include "../asterisk.h"
#include "../astconf.h"
static char *tdesc = "Extension Directory";
static char *app = "Directory";
static char *synopsis = "Provide directory of voicemail extensions";
static char *descrip =
" Directory(vm-context[|dial-context[|options]]): Presents the user with a directory\n"
"of extensions from which they may select by name. The list of names \n"
"and extensions is discovered from voicemail.conf. The vm-context argument\n"
"is required, and specifies the context of voicemail.conf to use. The\n"
"dial-context is the context to use for dialing the users, and defaults to\n"
"the vm-context if unspecified. The 'f' option causes the directory to match\n"
"based on the first name in voicemail.conf instead of the last name.\n"
"Returns 0 unless the user hangs up. It also sets up the channel on exit\n"
"to enter the extension the user selected.\n";
/* For simplicity, I'm keeping the format compatible with the voicemail config,
but i'm open to suggestions for isolating it */
@@ -115,6 +101,7 @@ static char *convert(char *lastname)
case 'Z':
tmp[lcount++] = '9';
break;
default:
}
lastname++;
}
@@ -123,114 +110,18 @@ static char *convert(char *lastname)
return tmp;
}
/* play name of mailbox owner.
* returns: -1 for bad or missing extension
* '1' for selected entry from directory
* '*' for skipped entry from directory
*/
static int play_mailbox_owner(struct ast_channel *chan, char *context, char *dialcontext, char *ext, char *name) {
int res = 0;
int loop = 3;
char fn[256];
char fn2[256];
/* Check for the VoiceMail2 greeting first */
snprintf(fn, sizeof(fn), "%s/voicemail/%s/%s/greet",
(char *)ast_config_AST_SPOOL_DIR, context, ext);
/* Otherwise, check for an old-style Voicemail greeting */
snprintf(fn2, sizeof(fn2), "%s/vm/%s/greet",
(char *)ast_config_AST_SPOOL_DIR, ext);
if (ast_fileexists(fn, NULL, chan->language) > 0) {
res = ast_streamfile(chan, fn, chan->language);
if (!res) {
res = ast_waitstream(chan, AST_DIGIT_ANY);
}
ast_stopstream(chan);
} else if (ast_fileexists(fn2, NULL, chan->language) > 0) {
res = ast_streamfile(chan, fn2, chan->language);
if (!res) {
res = ast_waitstream(chan, AST_DIGIT_ANY);
}
ast_stopstream(chan);
} else {
res = ast_say_character_str(chan, !ast_strlen_zero(name) ? name : ext,
AST_DIGIT_ANY, chan->language);
}
while (loop) {
if (!res) {
res = ast_streamfile(chan, "dir-instr", chan->language);
}
if (!res) {
res = ast_waitstream(chan, AST_DIGIT_ANY);
}
if (!res) {
res = ast_waitfordigit(chan, 3000);
}
ast_stopstream(chan);
if (res > -1) {
switch (res) {
case '1':
/* Name selected */
loop = 0;
if (ast_exists_extension(chan,dialcontext,ext,1,chan->callerid)) {
strncpy(chan->exten, ext, sizeof(chan->exten)-1);
chan->priority = 0;
strncpy(chan->context, dialcontext, sizeof(chan->context)-1);
} else {
ast_log(LOG_WARNING,
"Can't find extension '%s' in context '%s'. "
"Did you pass the wrong context to Directory?\n",
ext, dialcontext);
res = -1;
}
break;
case '*':
/* Skip to next match in list */
loop = 0;
break;
default:
/* Not '1', or '*', so decrement number of tries */
res = 0;
loop--;
break;
} /* end switch */
} /* end if */
else {
/* User hungup, so jump out now */
loop = 0;
}
} /* end while */
return(res);
}
static int do_directory(struct ast_channel *chan, struct ast_config *cfg, char *context, char *dialcontext, char digit, int last)
static int do_directory(struct ast_channel *chan, struct ast_config *cfg, char *context, char digit)
{
/* Read in the first three digits.. "digit" is the first digit, already read */
char ext[NUMDIGITS + 1];
char name[80] = "";
struct ast_variable *v;
int res;
int found=0;
int lastuserchoice = 0;
char *start, *pos, *conv,*stringp=NULL;
if (!context || ast_strlen_zero(context)) {
ast_log(LOG_WARNING,
"Directory must be called with an argument "
"(context in which to interpret extensions)\n");
return -1;
}
char *start, *pos, *conv;
char fn[256];
memset(ext, 0, sizeof(ext));
ext[0] = digit;
res = 0;
if (ast_readstring(chan, ext + 1, NUMDIGITS - 1, 3000, 3000, "#") < 0) res = -1;
res = ast_readstring(chan, ext + 1, NUMDIGITS, 3000, 3000, "#");
if (!res) {
/* Search for all names which start with those digits */
v = ast_variable_browse(cfg, context);
@@ -240,13 +131,11 @@ static int do_directory(struct ast_channel *chan, struct ast_config *cfg, char *
/* Find a candidate extension */
start = strdup(v->value);
if (start) {
stringp=start;
strsep(&stringp, ",");
pos = strsep(&stringp, ",");
strtok(start, ",");
pos = strtok(NULL, ",");
if (pos) {
strncpy(name, pos, sizeof(name) - 1);
/* Grab the last name */
if (last && strrchr(pos,' '))
if (strrchr(pos, ' '))
pos = strrchr(pos, ' ') + 1;
conv = convert(pos);
if (conv) {
@@ -264,46 +153,51 @@ static int do_directory(struct ast_channel *chan, struct ast_config *cfg, char *
}
v = v->next;
}
if (v) {
/* We have a match -- play a greeting if they have it */
res = play_mailbox_owner(chan, context, dialcontext, v->name, name);
switch (res) {
case -1:
/* user pressed '1' but extension does not exist, or
* user hungup
*/
lastuserchoice = 0;
break;
case '1':
/* user pressed '1' and extensions exists */
lastuserchoice = res;
strncpy(chan->context, dialcontext, sizeof(chan->context) - 1);
strncpy(chan->exten, v->name, sizeof(chan->exten) - 1);
snprintf(fn, sizeof(fn), "%s/vm/%s/greet", AST_SPOOL_DIR, v->name);
if (ast_fileexists(fn, NULL, chan->language)) {
res = ast_streamfile(chan, fn, chan->language);
if (!res)
res = ast_waitstream(chan, AST_DIGIT_ANY);
ast_stopstream(chan);
} else {
res = ast_say_digit_str(chan, v->name, chan->language);
}
ahem:
if (!res)
res = ast_streamfile(chan, "dir-instr", chan->language);
if (!res)
res = ast_waitstream(chan, AST_DIGIT_ANY);
if (!res)
res = ast_waitfordigit(chan, 3000);
ast_stopstream(chan);
if (res > -1) {
if (res == '1') {
strncpy(chan->exten, v->name, sizeof(chan->exten));
chan->priority = 0;
break;
case '*':
/* user pressed '*' to skip something found */
lastuserchoice = res;
strncpy(chan->context, context, sizeof(chan->context));
res = 0;
break;
default:
break;
} else if (res == '*') {
res = 0;
v = v->next;
} else {
res = 0;
goto ahem;
}
}
v = v->next;
} else {
if (found)
res = ast_streamfile(chan, "dir-nomore", chan->language);
else
res = ast_streamfile(chan, "dir-nomatch", chan->language);
if (!res)
res = 1;
return res;
}
}
if (lastuserchoice != '1') {
if (found)
res = ast_streamfile(chan, "dir-nomore", chan->language);
else
res = ast_streamfile(chan, "dir-nomatch", chan->language);
if (!res)
res = 1;
return res;
}
return 0;
}
return res;
}
@@ -313,11 +207,8 @@ static int directory_exec(struct ast_channel *chan, void *data)
int res = 0;
struct localuser *u;
struct ast_config *cfg;
int last = 1;
char *context, *dialcontext, *dirintro, *options;
if (!data) {
ast_log(LOG_WARNING, "directory requires an argument (context[,dialcontext])\n");
ast_log(LOG_WARNING, "directory requires an argument (context)\n");
return -1;
}
cfg = ast_load(DIRECTORY_CONFIG);
@@ -327,40 +218,15 @@ static int directory_exec(struct ast_channel *chan, void *data)
}
LOCAL_USER_ADD(u);
top:
context = ast_strdupa(data);
dialcontext = strchr(context, '|');
if (dialcontext) {
*dialcontext = '\0';
dialcontext++;
options = strchr(dialcontext, '|');
if (options) {
*options = '\0';
options++;
if (strchr(options, 'f'))
last = 0;
}
} else
dialcontext = context;
dirintro = ast_variable_retrieve(cfg, context, "directoryintro");
if (!dirintro || ast_strlen_zero(dirintro))
dirintro = ast_variable_retrieve(cfg, "general", "directoryintro");
if (!dirintro || ast_strlen_zero(dirintro)) {
if (last)
dirintro = "dir-intro";
else
dirintro = "dir-intro-fn";
}
if (chan->_state != AST_STATE_UP)
res = ast_answer(chan);
if (!res)
res = ast_streamfile(chan, dirintro, chan->language);
res = ast_streamfile(chan, "dir-intro", chan->language);
if (!res)
res = ast_waitstream(chan, AST_DIGIT_ANY);
ast_stopstream(chan);
if (!res)
res = ast_waitfordigit(chan, 5000);
if (res > 0) {
res = do_directory(chan, cfg, context, dialcontext, res, last);
res = do_directory(chan, cfg, (char *)data, res);
if (res > 0) {
res = ast_waitstream(chan, AST_DIGIT_ANY);
ast_stopstream(chan);
@@ -382,7 +248,7 @@ int unload_module(void)
int load_module(void)
{
return ast_register_application(app, directory_exec, synopsis, descrip);
return ast_register_application(app, directory_exec);
}
char *description(void)
@@ -396,8 +262,3 @@ int usecount(void)
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -1,365 +0,0 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* DISA -- Direct Inward System Access Application 6/20/2001
*
* Copyright (C) 2001, Linux Support Services, Inc.
*
* Jim Dixon <jim@lambdatel.com>
*
* Made only slightly more sane by Mark Spencer <markster@digium.com>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*/
#include <asterisk/lock.h>
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <asterisk/indications.h>
#include <asterisk/pbx.h>
#include <asterisk/module.h>
#include <asterisk/translate.h>
#include <asterisk/ulaw.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <sys/time.h>
static char *tdesc = "DISA (Direct Inward System Access) Application";
static char *app = "DISA";
static char *synopsis = "DISA (Direct Inward System Access)";
static char *descrip =
"DISA (Direct Inward System Access) -- Allows someone from outside\n"
"the telephone switch (PBX) to obtain an \"internal\" system dialtone\n"
"and to place calls from it as if they were placing a call from within\n"
"the switch. A user calls a number that connects to the DISA application\n"
"and is given dialtone. The user enters their passcode, followed by the\n"
"pound sign (#). If the passcode is correct, the user is then given\n"
"system dialtone on which a call may be placed. Obviously, this type\n"
"of access has SERIOUS security implications, and GREAT care must be\n"
"taken NOT to compromise your security.\n\n"
"There is a possibility of accessing DISA without password. Simply\n"
"exchange your password with no-password.\n\n"
" Example: exten => s,1,DISA,no-password|local\n\n"
"but be aware of using this for your security compromising.\n\n"
"The arguments to this application (in extensions.conf) allow either\n"
"specification of a single global password (that everyone uses), or\n"
"individual passwords contained in a file. It also allow specification\n"
"of the context on which the user will be dialing. If no context is\n"
"specified, the DISA application defaults the context to \"disa\"\n"
"presumably that a normal system will have a special context set up\n"
"for DISA use with some or a lot of restrictions. The arguments are\n"
"one of the following:\n\n"
" numeric-passcode\n"
" numeric-passcode|context\n"
" full-pathname-of-file-that-contains-passcodes\n\n"
"The file that contains the passcodes (if used) allows specification\n"
"of either just a passcode (defaulting to the \"disa\" context, or\n"
"passcode|context on each line of the file. The file may contain blank\n"
"lines, or comments starting with \"#\" or \";\". In addition, the\n"
"above arguments may have |new-callerid-string appended to them, to\n"
"specify a new (different) callerid to be used for this call, for\n"
"example: numeric-passcode|context|\"My Phone\" <(234) 123-4567> or \n"
"full-pathname-of-passcode-file|\"My Phone\" <(234) 123-4567>. Note that\n"
"in the case of specifying the numeric-passcode, the context must be\n"
"specified if the callerid is specified also.\n\n"
"If login is successful, the application parses the dialed number in\n"
"the specified (or default) context, and returns 0 with the new extension\n"
"context filled-in and the priority set to 1, so that the PBX may\n"
"re-apply the routing tables to it and complete the call normally.";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
static int firstdigittimeout = 20000; /* 20 seconds first digit timeout */
static int digittimeout = 10000; /* 10 seconds subsequent digit timeout */
static int ms_diff(struct timeval *tv1, struct timeval *tv2)
{
int ms;
ms = (tv1->tv_sec - tv2->tv_sec) * 1000;
ms += (tv1->tv_usec - tv2->tv_usec) / 1000;
return(ms);
}
static void play_dialtone(struct ast_channel *chan)
{
const struct tone_zone_sound *ts = NULL;
ts = ast_get_indication_tone(chan->zone, "dial");
if (ts)
ast_playtones_start(chan, 0, ts->data, 0);
else
ast_tonepair_start(chan, 350, 440, 0, 0);
}
static int disa_exec(struct ast_channel *chan, void *data)
{
int i,j,k,x,did_ignore;
struct localuser *u;
char tmp[256],arg2[256]="",exten[AST_MAX_EXTENSION],acctcode[20]="";
char *ourcontext,*ourcallerid;
struct ast_frame *f;
struct timeval lastout, now, lastdigittime;
int res;
time_t rstart;
FILE *fp;
char *stringp=NULL;
if (ast_set_write_format(chan,AST_FORMAT_ULAW))
{
ast_log(LOG_WARNING, "Unable to set write format to Mu-law on %s\n",chan->name);
return -1;
}
if (ast_set_read_format(chan,AST_FORMAT_ULAW))
{
ast_log(LOG_WARNING, "Unable to set read format to Mu-law on %s\n",chan->name);
return -1;
}
lastout.tv_sec = lastout.tv_usec = 0;
if (!data || !strlen((char *)data)) {
ast_log(LOG_WARNING, "disa requires an argument (passcode/passcode file)\n");
return -1;
}
strncpy(tmp, (char *)data, sizeof(tmp)-1);
stringp=tmp;
strsep(&stringp, "|");
ourcontext = strsep(&stringp, "|");
/* if context specified, save 2nd arg and parse third */
if (ourcontext) {
strncpy(arg2,ourcontext, sizeof(arg2) - 1);
ourcallerid = strsep(&stringp,"|");
}
/* if context not specified, use "disa" */
else {
arg2[0] = 0;
ourcallerid = NULL;
ourcontext = "disa";
}
LOCAL_USER_ADD(u);
if (chan->_state != AST_STATE_UP)
{
/* answer */
ast_answer(chan);
}
i = k = x = 0; /* k is 0 for pswd entry, 1 for ext entry */
did_ignore = 0;
exten[0] = 0;
acctcode[0] = 0;
/* can we access DISA without password? */
ast_log(LOG_DEBUG, "Context: %s\n",ourcontext);
if (!strcasecmp(tmp, "no-password"))
{;
k = 1;
ast_log(LOG_DEBUG, "DISA no-password login success\n");
}
gettimeofday(&lastdigittime,NULL);
play_dialtone(chan);
for(;;)
{
gettimeofday(&now,NULL);
/* if outa time, give em reorder */
if (ms_diff(&now,&lastdigittime) >
((k) ? digittimeout : firstdigittimeout))
{
ast_log(LOG_DEBUG,"DISA %s entry timeout on chan %s\n",
((k) ? "extension" : "password"),chan->name);
break;
}
if ((res = ast_waitfor(chan, -1) < 0)) {
ast_log(LOG_DEBUG, "Waitfor returned %d\n", res);
continue;
}
f = ast_read(chan);
if (f == NULL)
{
LOCAL_USER_REMOVE(u);
return -1;
}
if ((f->frametype == AST_FRAME_CONTROL) &&
(f->subclass == AST_CONTROL_HANGUP))
{
ast_frfree(f);
LOCAL_USER_REMOVE(u);
return -1;
}
if (f->frametype == AST_FRAME_VOICE) {
ast_frfree(f);
continue;
}
/* if not DTMF, just do it again */
if (f->frametype != AST_FRAME_DTMF)
{
ast_frfree(f);
continue;
}
j = f->subclass; /* save digit */
ast_frfree(f);
if (i == 0)
ast_playtones_stop(chan);
gettimeofday(&lastdigittime,NULL);
/* got a DTMF tone */
if (i < AST_MAX_EXTENSION) /* if still valid number of digits */
{
if (!k) /* if in password state */
{
if (j == '#') /* end of password */
{
/* see if this is an integer */
if (sscanf(tmp,"%d",&j) < 1)
{ /* nope, it must be a filename */
fp = fopen(tmp,"r");
if (!fp)
{
ast_log(LOG_WARNING,"DISA password file %s not found on chan %s\n",tmp,chan->name);
LOCAL_USER_REMOVE(u);
return -1;
}
tmp[0] = 0;
while(fgets(tmp,sizeof(tmp) - 1,fp))
{
char *stringp=NULL,*stringp2;
if (!tmp[0]) continue;
if (tmp[strlen(tmp) - 1] == '\n')
tmp[strlen(tmp) - 1] = 0;
if (!tmp[0]) continue;
/* skip comments */
if (tmp[0] == '#') continue;
if (tmp[0] == ';') continue;
stringp=tmp;
strsep(&stringp, "|");
stringp2=strsep(&stringp, "|");
if (stringp2) {
ourcontext=stringp2;
stringp2=strsep(&stringp, "|");
if (stringp2) ourcallerid=stringp2;
}
/* password must be in valid format (numeric) */
if (sscanf(tmp,"%d",&j) < 1) continue;
/* if we got it */
if (!strcmp(exten,tmp)) break;
}
fclose(fp);
}
/* compare the two */
if (strcmp(exten,tmp))
{
ast_log(LOG_WARNING,"DISA on chan %s got bad password %s\n",chan->name,exten);
goto reorder;
}
/* password good, set to dial state */
ast_log(LOG_DEBUG,"DISA on chan %s password is good\n",chan->name);
play_dialtone(chan);
k = 1;
i = 0; /* re-set buffer pointer */
exten[sizeof(acctcode)] = 0;
strncpy(acctcode,exten, sizeof(acctcode) - 1);
exten[0] = 0;
ast_log(LOG_DEBUG,"Successful DISA log-in on chan %s\n",chan->name);
continue;
}
}
exten[i++] = j; /* save digit */
exten[i] = 0;
if (!k) continue; /* if getting password, continue doing it */
/* if this exists */
if (ast_ignore_pattern(ourcontext, exten)) {
play_dialtone(chan);
did_ignore = 1;
} else
if (did_ignore) {
ast_playtones_stop(chan);
did_ignore = 0;
}
/* if can do some more, do it */
if (!ast_matchmore_extension(chan,ourcontext,exten,1, chan->callerid)) {
break;
}
}
}
if (k && ast_exists_extension(chan,ourcontext,exten,1, chan->callerid))
{
ast_playtones_stop(chan);
/* We're authenticated and have a valid extension */
if (ourcallerid && *ourcallerid)
{
if (chan->callerid) free(chan->callerid);
chan->callerid = strdup(ourcallerid);
}
strncpy(chan->exten, exten, sizeof(chan->exten) - 1);
strncpy(chan->context, ourcontext, sizeof(chan->context) - 1);
strncpy(chan->accountcode, acctcode, sizeof(chan->accountcode) - 1);
chan->priority = 0;
ast_cdr_init(chan->cdr,chan);
LOCAL_USER_REMOVE(u);
return 0;
}
reorder:
ast_indicate(chan,AST_CONTROL_CONGESTION);
/* something is invalid, give em reorder for several seconds */
time(&rstart);
while(time(NULL) < rstart + 10)
{
if (ast_waitfor(chan, -1) < 0)
break;
f = ast_read(chan);
if (!f)
break;
ast_frfree(f);
}
ast_playtones_stop(chan);
LOCAL_USER_REMOVE(u);
return -1;
}
int unload_module(void)
{
STANDARD_HANGUP_LOCALUSERS;
return ast_unregister_application(app);
}
int load_module(void)
{
return ast_register_application(app, disa_exec, synopsis, descrip);
}
char *description(void)
{
return tdesc;
}
int usecount(void)
{
int res;
STANDARD_USECOUNT(res);
return res;
}
char *key(void)
{
return ASTERISK_GPL_KEY;
}

View File

@@ -11,7 +11,6 @@
* the GNU General Public License
*/
#include <asterisk/lock.h>
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
@@ -22,41 +21,28 @@
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
static char *tdesc = "Simple Echo Application";
static char *app = "Echo";
static char *synopsis = "Echo audio read back to the user";
static char *descrip =
" Echo(): Echo audio read from channel back to the channel. Returns 0\n"
"if the user exits with the '#' key, or -1 if the user hangs up.\n";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
static int echo_exec(struct ast_channel *chan, void *data)
static int skel_exec(struct ast_channel *chan, void *data)
{
int res=-1;
struct localuser *u;
struct ast_frame *f;
LOCAL_USER_ADD(u);
ast_set_write_format(chan, ast_best_codec(chan->nativeformats));
ast_set_read_format(chan, ast_best_codec(chan->nativeformats));
/* Do our thing here */
while(ast_waitfor(chan, -1) > -1) {
f = ast_read(chan);
if (!f)
break;
f->delivery.tv_sec = 0;
f->delivery.tv_usec = 0;
while((f = ast_read(chan))) {
if (f->frametype == AST_FRAME_VOICE) {
if (ast_write(chan, f))
break;
} else if (f->frametype == AST_FRAME_VIDEO) {
if (ast_write(chan, f))
break;
} else if (f->frametype == AST_FRAME_DTMF) {
if (f->subclass == '#') {
res = 0;
@@ -65,7 +51,6 @@ static int echo_exec(struct ast_channel *chan, void *data)
if (ast_write(chan, f))
break;
}
ast_frfree(f);
}
LOCAL_USER_REMOVE(u);
return res;
@@ -79,7 +64,7 @@ int unload_module(void)
int load_module(void)
{
return ast_register_application(app, echo_exec, synopsis, descrip);
return ast_register_application(app, skel_exec);
}
char *description(void)
@@ -93,8 +78,3 @@ int usecount(void)
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -1,203 +0,0 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* Time of day - Report the time of day
*
* Copyright (C) 1999, Mark Spencer
*
* Mark Spencer <markster@linux-support.net>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*/
#include <asterisk/lock.h>
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <asterisk/pbx.h>
#include <asterisk/options.h>
#include <asterisk/config.h>
#include <asterisk/module.h>
#include <asterisk/enum.h>
#include <asterisk/utils.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
static char *tdesc = "ENUM Lookup";
static char *app = "EnumLookup";
static char *synopsis = "Lookup number in ENUM";
static char *descrip =
" EnumLookup(exten): Looks up an extension via ENUM and sets\n"
"the variable 'ENUM'. For VoIP URIs this variable will \n"
"look like 'TECHNOLOGY/URI' with the appropriate technology.\n"
"Returns -1 on hangup, or 0 on completion regardless of whether the \n"
"lookup was successful. \n"
"Currently, the enumservices SIP, H323, IAX, IAX2 and TEL are recognized. \n"
"A good SIP, H323, IAX or IAX2 entry will result in normal priority handling, \n"
"whereas a good TEL entry will increase the priority by 51 (if existing).\n"
"If the lookup was *not* successful and there exists a priority n + 101,\n"
"then that priority will be taken next.\n" ;
#define ENUM_CONFIG "enum.conf"
static char h323driver[80] = "";
#define H323DRIVERDEFAULT "H323"
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
static int enumlookup_exec(struct ast_channel *chan, void *data)
{
int res=0;
char tech[80];
char dest[80];
char tmp[256];
char *c,*t;
struct localuser *u;
if (!data || ast_strlen_zero(data)) {
ast_log(LOG_WARNING, "EnumLookup requires an argument (extension)\n");
res = 1;
}
LOCAL_USER_ADD(u);
if (!res) {
res = ast_get_enum(chan, data, dest, sizeof(dest), tech, sizeof(tech));
printf("ENUM got '%d'\n", res);
}
LOCAL_USER_REMOVE(u);
/* Parse it out */
if (res > 0) {
if (!strcasecmp(tech, "SIP")) {
c = dest;
if (!strncmp(c, "sip:", 4))
c += 4;
snprintf(tmp, sizeof(tmp), "SIP/%s", c);
pbx_builtin_setvar_helper(chan, "ENUM", tmp);
} else if (!strcasecmp(tech, "h323")) {
c = dest;
if (!strncmp(c, "h323:", 5))
c += 5;
snprintf(tmp, sizeof(tmp), "%s/%s", h323driver, c);
/* do a s!;.*!! on the H323 URI */
t = strchr(c,';');
if (t)
*t = 0;
pbx_builtin_setvar_helper(chan, "ENUM", tmp);
} else if (!strcasecmp(tech, "iax")) {
c = dest;
if (!strncmp(c, "iax:", 4))
c += 4;
snprintf(tmp, sizeof(tmp), "IAX/%s", c);
pbx_builtin_setvar_helper(chan, "ENUM", tmp);
} else if (!strcasecmp(tech, "iax2")) {
c = dest;
if (!strncmp(c, "iax2:", 5))
c += 5;
snprintf(tmp, sizeof(tmp), "IAX2/%s", c);
pbx_builtin_setvar_helper(chan, "ENUM", tmp);
} else if (!strcasecmp(tech, "tel")) {
c = dest;
if (!strncmp(c, "tel:", 4))
c += 4;
if (c[0] != '+') {
ast_log(LOG_NOTICE, "tel: uri must start with a \"+\" (got '%s')\n", c);
res = 0;
} else {
/* now copy over the number, skipping all non-digits and stop at ; or NULL */
t = tmp;
while( *c && (*c != ';') && (t - tmp < (sizeof(tmp) - 1))) {
if (isdigit(*c))
*t++ = *c;
c++;
}
*t = 0;
pbx_builtin_setvar_helper(chan, "ENUM", tmp);
ast_log(LOG_NOTICE, "tel: ENUM set to \"%s\"\n", tmp);
if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 51, chan->callerid))
chan->priority += 50;
else
res = 0;
}
} else if (!ast_strlen_zero(tech)) {
ast_log(LOG_NOTICE, "Don't know how to handle technology '%s'\n", tech);
res = 0;
}
}
if (!res) {
/* Look for a "busy" place */
if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 101, chan->callerid))
chan->priority += 100;
} else if (res > 0)
res = 0;
return res;
}
static int load_config(void)
{
struct ast_config *cfg;
char *s;
cfg = ast_load(ENUM_CONFIG);
if (cfg) {
if (!(s=ast_variable_retrieve(cfg, "general", "h323driver"))) {
strncpy(h323driver, H323DRIVERDEFAULT, sizeof(h323driver) - 1);
} else {
strncpy(h323driver, s, sizeof(h323driver) - 1);
}
ast_destroy(cfg);
return 0;
}
ast_log(LOG_NOTICE, "No ENUM Config file, using defaults\n");
return 0;
}
int unload_module(void)
{
STANDARD_HANGUP_LOCALUSERS;
return ast_unregister_application(app);
}
int load_module(void)
{
int res;
res = ast_register_application(app, enumlookup_exec, synopsis, descrip);
if (res)
return(res);
if ((res=load_config())) {
return(res);
}
return(0);
}
int reload(void)
{
return(load_config());
}
char *description(void)
{
return tdesc;
}
int usecount(void)
{
int res;
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -1,101 +0,0 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* Eval application
*
* Copyright (c) 2004 Tilghman Lesher. All rights reserved.
*
* Tilghman Lesher <app_eval__v001@the-tilghman.com>
*
* $Id$
*
* This code is released by the author with no restrictions on usage.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/options.h>
#include <asterisk/channel.h>
#include <asterisk/pbx.h>
#include <asterisk/module.h>
/* Maximum length of any variable */
#define MAXRESULT 1024
static char *tdesc = "Reevaluates strings";
static char *app_eval = "Eval";
static char *eval_synopsis = "Eval(newvar=somestring)";
static char *eval_descrip =
"Eval(newvar=somestring)\n"
" Normally Asterisk evaluates variables inline. But what if you want to\n"
"store variable offsets in a database, to be evaluated later? Eval is\n"
"the answer, by allowing a string to be evaluated twice in the dialplan,\n"
"the first time as part of the normal dialplan, and the second using Eval.\n";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
static int eval_exec(struct ast_channel *chan, void *data)
{
int res=0;
struct localuser *u;
char *s, *newvar=NULL, tmp[MAXRESULT];
LOCAL_USER_ADD(u);
/* Check and parse arguments */
if (data) {
s = ast_strdupa((char *)data);
if (s) {
newvar = strsep(&s, "=");
if (newvar && (newvar[0] != '\0')) {
memset(tmp, 0, MAXRESULT);
pbx_substitute_variables_helper(chan, s, tmp, MAXRESULT - 1);
pbx_builtin_setvar_helper(chan, newvar, tmp);
}
} else {
ast_log(LOG_ERROR, "Out of memory\n");
res = -1;
}
}
LOCAL_USER_REMOVE(u);
return res;
}
int unload_module(void)
{
STANDARD_HANGUP_LOCALUSERS;
return ast_unregister_application(app_eval);
}
int load_module(void)
{
return ast_register_application(app_eval, eval_exec, eval_synopsis, eval_descrip);
}
char *description(void)
{
return tdesc;
}
int usecount(void)
{
int res;
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -1,113 +0,0 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* Exec application
*
* Copyright (c) 2004 Tilghman Lesher. All rights reserved.
*
* Tilghman Lesher <app_exec__v001@the-tilghman.com>
*
* $Id$
*
* This code is released by the author with no restrictions on usage.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/options.h>
#include <asterisk/channel.h>
#include <asterisk/pbx.h>
#include <asterisk/module.h>
/* Maximum length of any variable */
#define MAXRESULT 1024
static char *tdesc = "Executes applications";
static char *app_exec = "Exec";
static char *exec_synopsis = "Exec(Appname(arguments))";
static char *exec_descrip =
"Exec(appname(arguments))\n"
" Allows an arbitrary application to be invoked even when not\n"
"hardcoded into the dialplan. Returns whatever value the\n"
"app returns or -2 when the app cannot be found.\n";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
static int exec_exec(struct ast_channel *chan, void *data)
{
int res=0;
struct localuser *u;
char *s, *appname, *endargs, args[MAXRESULT];
struct ast_app *app;
LOCAL_USER_ADD(u);
memset(args, 0, MAXRESULT);
/* Check and parse arguments */
if (data) {
s = ast_strdupa((char *)data);
if (s) {
appname = strsep(&s, "(");
if (s) {
endargs = strrchr(s, ')');
if (endargs)
*endargs = '\0';
pbx_substitute_variables_helper(chan, s, args, MAXRESULT - 1);
}
if (appname) {
app = pbx_findapp(appname);
if (app) {
res = pbx_exec(chan, app, args, 1);
} else {
ast_log(LOG_WARNING, "Could not find application (%s)\n", appname);
res = -2;
}
}
} else {
ast_log(LOG_ERROR, "Out of memory\n");
res = -1;
}
}
LOCAL_USER_REMOVE(u);
return res;
}
int unload_module(void)
{
STANDARD_HANGUP_LOCALUSERS;
return ast_unregister_application(app_exec);
}
int load_module(void)
{
return ast_register_application(app_exec, exec_exec, exec_synopsis, exec_descrip);
}
char *description(void)
{
return tdesc;
}
int usecount(void)
{
int res;
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -1,483 +0,0 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* Connect to festival
*
* Copyright (C) 2002, Christos Ricudis
*
* Christos Ricudis <ricudis@itc.auth.gr>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*/
#include <sys/types.h>
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <asterisk/pbx.h>
#include <asterisk/module.h>
#include <asterisk/md5.h>
#include <asterisk/config.h>
#include <asterisk/utils.h>
#include <asterisk/lock.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <ctype.h>
#define FESTIVAL_CONFIG "festival.conf"
static char *tdesc = "Simple Festival Interface";
static char *app = "Festival";
static char *synopsis = "Say text to the user";
static char *descrip =
" Festival(text[|intkeys]): Connect to Festival, send the argument, get back the waveform,"
"play it to the user, allowing any given interrupt keys to immediately terminate and return\n"
"the value, or 'any' to allow any number back (useful in dialplan)\n";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
static char *socket_receive_file_to_buff(int fd,int *size)
{
/* Receive file (probably a waveform file) from socket using */
/* Festival key stuff technique, but long winded I know, sorry */
/* but will receive any file without closeing the stream or */
/* using OOB data */
static char *file_stuff_key = "ft_StUfF_key"; /* must == Festival's key */
char *buff;
int bufflen;
int n,k,i;
char c;
bufflen = 1024;
buff = (char *)malloc(bufflen);
*size=0;
for (k=0; file_stuff_key[k] != '\0';)
{
n = read(fd,&c,1);
if (n==0) break; /* hit stream eof before end of file */
if ((*size)+k+1 >= bufflen)
{ /* +1 so you can add a NULL if you want */
bufflen += bufflen/4;
buff = (char *)realloc(buff,bufflen);
}
if (file_stuff_key[k] == c)
k++;
else if ((c == 'X') && (file_stuff_key[k+1] == '\0'))
{ /* It looked like the key but wasn't */
for (i=0; i < k; i++,(*size)++)
buff[*size] = file_stuff_key[i];
k=0;
/* omit the stuffed 'X' */
}
else
{
for (i=0; i < k; i++,(*size)++)
buff[*size] = file_stuff_key[i];
k=0;
buff[*size] = c;
(*size)++;
}
}
return buff;
}
static int send_waveform_to_fd(char *waveform, int length, int fd) {
int res;
int x;
#ifdef __PPC__
char c;
#endif
res = fork();
if (res < 0)
ast_log(LOG_WARNING, "Fork failed\n");
if (res)
return res;
for (x=0;x<256;x++) {
if (x != fd)
close(x);
}
//IAS
#ifdef __PPC__
for( x=0; x<length; x+=2)
{
c = *(waveform+x+1);
*(waveform+x+1)=*(waveform+x);
*(waveform+x)=c;
}
#endif
write(fd,waveform,length);
write(fd,"a",1);
close(fd);
exit(0);
}
static int send_waveform_to_channel(struct ast_channel *chan, char *waveform, int length, char *intkeys) {
int res=0;
int fds[2];
int ms = -1;
int pid = -1;
int needed = 0;
int owriteformat;
struct ast_frame *f;
struct myframe {
struct ast_frame f;
char offset[AST_FRIENDLY_OFFSET];
char frdata[2048];
} myf;
if (pipe(fds)) {
ast_log(LOG_WARNING, "Unable to create pipe\n");
return -1;
}
/* Answer if it's not already going */
if (chan->_state != AST_STATE_UP)
ast_answer(chan);
ast_stopstream(chan);
owriteformat = chan->writeformat;
res = ast_set_write_format(chan, AST_FORMAT_SLINEAR);
if (res < 0) {
ast_log(LOG_WARNING, "Unable to set write format to signed linear\n");
return -1;
}
res=send_waveform_to_fd(waveform,length,fds[1]);
if (res >= 0) {
pid = res;
/* Order is important -- there's almost always going to be mp3... we want to prioritize the
user */
for (;;) {
ms = 1000;
res = ast_waitfor(chan, ms);
if (res < 1) {
res = -1;
break;
}
f = ast_read(chan);
if (!f) {
ast_log(LOG_WARNING, "Null frame == hangup() detected\n");
res = -1;
break;
}
if (f->frametype == AST_FRAME_DTMF) {
ast_log(LOG_DEBUG, "User pressed a key\n");
if (intkeys && strchr(intkeys, f->subclass)) {
res = f->subclass;
ast_frfree(f);
break;
}
}
if (f->frametype == AST_FRAME_VOICE) {
/* Treat as a generator */
needed = f->samples * 2;
if (needed > sizeof(myf.frdata)) {
ast_log(LOG_WARNING, "Only able to deliver %d of %d requested samples\n",
(int)sizeof(myf.frdata) / 2, needed/2);
needed = sizeof(myf.frdata);
}
res = read(fds[0], myf.frdata, needed);
if (res > 0) {
myf.f.frametype = AST_FRAME_VOICE;
myf.f.subclass = AST_FORMAT_SLINEAR;
myf.f.datalen = res;
myf.f.samples = res / 2;
myf.f.mallocd = 0;
myf.f.offset = AST_FRIENDLY_OFFSET;
myf.f.src = __PRETTY_FUNCTION__;
myf.f.data = myf.frdata;
if (ast_write(chan, &myf.f) < 0) {
res = -1;
break;
}
if (res < needed) { // last frame
ast_log(LOG_DEBUG, "Last frame\n");
res=0;
break;
}
} else {
ast_log(LOG_DEBUG, "No more waveform\n");
res = 0;
}
}
ast_frfree(f);
}
}
close(fds[0]);
close(fds[1]);
// if (pid > -1)
// kill(pid, SIGKILL);
if (!res && owriteformat)
ast_set_write_format(chan, owriteformat);
return res;
}
#define MAXLEN 180
#define MAXFESTLEN 2048
static int festival_exec(struct ast_channel *chan, void *vdata)
{
int usecache;
int res=0;
struct localuser *u;
struct sockaddr_in serv_addr;
struct hostent *serverhost;
struct ast_hostent ahp;
int fd;
FILE *fs;
char *host;
char *cachedir;
char *temp;
char *festivalcommand;
int port=1314;
int n;
char ack[4];
char *waveform;
int filesize;
int wave;
char bigstring[MAXFESTLEN];
int i;
struct MD5Context md5ctx;
unsigned char MD5Res[16];
char MD5Hex[33] = "";
char koko[4] = "";
char cachefile[MAXFESTLEN]="";
int readcache=0;
int writecache=0;
int strln;
int fdesc = -1;
char buffer[16384];
int seekpos = 0;
char data[256] = "";
char *intstr;
struct ast_config *cfg;
cfg = ast_load(FESTIVAL_CONFIG);
if (!cfg) {
ast_log(LOG_WARNING, "No such configuration file %s\n", FESTIVAL_CONFIG);
return -1;
}
if (!(host = ast_variable_retrieve(cfg, "general", "host"))) {
host = "localhost";
}
if (!(temp = ast_variable_retrieve(cfg, "general", "port"))) {
port = 1314;
} else {
port = atoi(temp);
}
if (!(temp = ast_variable_retrieve(cfg, "general", "usecache"))) {
usecache=0;
} else {
usecache = ast_true(temp);
}
if (!(cachedir = ast_variable_retrieve(cfg, "general", "cachedir"))) {
cachedir = "/tmp/";
}
if (!(festivalcommand = ast_variable_retrieve(cfg, "general", "festivalcommand"))) {
festivalcommand = "(tts_textasterisk \"%s\" 'file)(quit)\n";
}
if (!vdata || ast_strlen_zero(vdata)) {
ast_log(LOG_WARNING, "festival requires an argument (text)\n");
ast_destroy(cfg);
return -1;
}
strncpy(data, vdata, sizeof(data) - 1);
if ((intstr = strchr(data, '|'))) {
*intstr = '\0';
intstr++;
if (!strcasecmp(intstr, "any"))
intstr = AST_DIGIT_ANY;
}
LOCAL_USER_ADD(u);
ast_log(LOG_DEBUG, "Text passed to festival server : %s\n",(char *)data);
/* Connect to local festival server */
fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (fd < 0) {
ast_log(LOG_WARNING,"festival_client: can't get socket\n");
ast_destroy(cfg);
return -1;
}
memset(&serv_addr, 0, sizeof(serv_addr));
if ((serv_addr.sin_addr.s_addr = inet_addr(host)) == -1) {
/* its a name rather than an ipnum */
serverhost = ast_gethostbyname(host, &ahp);
if (serverhost == (struct hostent *)0) {
ast_log(LOG_WARNING,"festival_client: gethostbyname failed\n");
ast_destroy(cfg);
return -1;
}
memmove(&serv_addr.sin_addr,serverhost->h_addr, serverhost->h_length);
}
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(port);
if (connect(fd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) != 0) {
ast_log(LOG_WARNING,"festival_client: connect to server failed\n");
ast_destroy(cfg);
return -1;
}
/* Compute MD5 sum of string */
MD5Init(&md5ctx);
MD5Update(&md5ctx,(unsigned char const *)data,strlen(data));
MD5Final(MD5Res,&md5ctx);
MD5Hex[0] = '\0';
/* Convert to HEX and look if there is any matching file in the cache
directory */
for (i=0;i<16;i++) {
snprintf(koko, sizeof(koko), "%X",MD5Res[i]);
strncat(MD5Hex, koko, sizeof(MD5Hex) - strlen(MD5Hex) - 1);
}
readcache=0;
writecache=0;
if (strlen(cachedir)+strlen(MD5Hex)+1<=MAXFESTLEN && (usecache==-1)) {
snprintf(cachefile, sizeof(cachefile), "%s/%s", cachedir, MD5Hex);
fdesc=open(cachefile,O_RDWR);
if (fdesc==-1) {
fdesc=open(cachefile,O_CREAT|O_RDWR,0777);
if (fdesc!=-1) {
writecache=1;
strln=strlen((char *)data);
ast_log(LOG_DEBUG,"line length : %d\n",strln);
write(fdesc,&strln,sizeof(int));
write(fdesc,data,strln);
seekpos=lseek(fdesc,0,SEEK_CUR);
ast_log(LOG_DEBUG,"Seek position : %d\n",seekpos);
}
} else {
read(fdesc,&strln,sizeof(int));
ast_log(LOG_DEBUG,"Cache file exists, strln=%d, strlen=%d\n",strln,(int)strlen((char *)data));
if (strlen((char *)data)==strln) {
ast_log(LOG_DEBUG,"Size OK\n");
read(fdesc,&bigstring,strln);
bigstring[strln] = 0;
if (strcmp(bigstring,data)==0) {
readcache=1;
} else {
ast_log(LOG_WARNING,"Strings do not match\n");
}
} else {
ast_log(LOG_WARNING,"Size mismatch\n");
}
}
}
if (readcache==1) {
close(fd);
fd=fdesc;
ast_log(LOG_DEBUG,"Reading from cache...\n");
} else {
ast_log(LOG_DEBUG,"Passing text to festival...\n");
fs=fdopen(dup(fd),"wb");
fprintf(fs,festivalcommand,(char *)data);
fflush(fs);
fclose(fs);
}
/* Write to cache and then pass it down */
if (writecache==1) {
ast_log(LOG_DEBUG,"Writing result to cache...\n");
while ((strln=read(fd,buffer,16384))!=0) {
write(fdesc,buffer,strln);
}
close(fd);
close(fdesc);
fd=open(cachefile,O_RDWR);
lseek(fd,seekpos,SEEK_SET);
}
ast_log(LOG_DEBUG,"Passing data to channel...\n");
/* Read back info from server */
/* This assumes only one waveform will come back, also LP is unlikely */
wave = 0;
do {
for (n=0; n < 3; )
n += read(fd,ack+n,3-n);
ack[3] = '\0';
if (strcmp(ack,"WV\n") == 0) { /* receive a waveform */
ast_log(LOG_DEBUG,"Festival WV command\n");
waveform = socket_receive_file_to_buff(fd,&filesize);
res = send_waveform_to_channel(chan,waveform,filesize, intstr);
free(waveform);
break;
}
else if (strcmp(ack,"LP\n") == 0) { /* receive an s-expr */
ast_log(LOG_DEBUG,"Festival LP command\n");
waveform = socket_receive_file_to_buff(fd,&filesize);
waveform[filesize]='\0';
ast_log(LOG_WARNING,"Festival returned LP : %s\n",waveform);
free(waveform);
} else if (strcmp(ack,"ER\n") == 0) { /* server got an error */
ast_log(LOG_WARNING,"Festival returned ER\n");
res=-1;
break;
}
} while (strcmp(ack,"OK\n") != 0);
close(fd);
ast_destroy(cfg);
LOCAL_USER_REMOVE(u);
return res;
}
int unload_module(void)
{
STANDARD_HANGUP_LOCALUSERS;
return ast_unregister_application(app);
}
int load_module(void)
{
return ast_register_application(app, festival_exec, synopsis, descrip);
}
char *description(void)
{
return tdesc;
}
int usecount(void)
{
int res;
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -1,119 +0,0 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* App to flash a zap trunk
*
* Copyright (C) 1999, Mark Spencer
*
* Mark Spencer <markster@linux-support.net>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*/
#include <asterisk/lock.h>
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <asterisk/pbx.h>
#include <asterisk/module.h>
#include <asterisk/translate.h>
#include <asterisk/image.h>
#include <asterisk/options.h>
#include <sys/ioctl.h>
#ifdef __linux__
#include <linux/zaptel.h>
#else
#include <zaptel.h>
#endif /* __linux__ */
#include <string.h>
#include <errno.h>
#include <stdlib.h>
static char *tdesc = "Flash zap trunk application";
static char *app = "Flash";
static char *synopsis = "Flashes a Zap Trunk";
static char *descrip =
" Flash(): Sends a flash on a zap trunk. This is only a hack for\n"
"people who want to perform transfers and such via AGI and is generally\n"
"quite useless otherwise. Returns 0 on success or -1 if this is not\n"
"a zap trunk\n";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
static inline int zt_wait_event(int fd)
{
/* Avoid the silly zt_waitevent which ignores a bunch of events */
int i,j=0;
i = ZT_IOMUX_SIGEVENT;
if (ioctl(fd, ZT_IOMUX, &i) == -1) return -1;
if (ioctl(fd, ZT_GETEVENT, &j) == -1) return -1;
return j;
}
static int flash_exec(struct ast_channel *chan, void *data)
{
int res = -1;
int x;
struct localuser *u;
struct zt_params ztp;
LOCAL_USER_ADD(u);
if (!strcasecmp(chan->type, "Zap")) {
memset(&ztp, 0, sizeof(ztp));
res = ioctl(chan->fds[0], ZT_GET_PARAMS, &ztp);
if (!res) {
if (ztp.sigtype & __ZT_SIG_FXS) {
x = ZT_FLASH;
res = ioctl(chan->fds[0], ZT_HOOK, &x);
if (!res || (errno == EINPROGRESS)) {
if (res) {
/* Wait for the event to finish */
zt_wait_event(chan->fds[0]);
}
res = ast_safe_sleep(chan, 1000);
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "Flashed channel %s\n", chan->name);
} else
ast_log(LOG_WARNING, "Unable to flash channel %s: %s\n", chan->name, strerror(errno));
} else
ast_log(LOG_WARNING, "%s is not an FXO Channel\n", chan->name);
} else
ast_log(LOG_WARNING, "Unable to get parameters of %s: %s\n", chan->name, strerror(errno));
} else
ast_log(LOG_WARNING, "%s is not a Zap channel\n", chan->name);
LOCAL_USER_REMOVE(u);
return res;
}
int unload_module(void)
{
STANDARD_HANGUP_LOCALUSERS;
return ast_unregister_application(app);
}
int load_module(void)
{
return ast_register_application(app, flash_exec, synopsis, descrip);
}
char *description(void)
{
return tdesc;
}
int usecount(void)
{
int res;
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -1,90 +0,0 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* Fork CDR application
* Copyright Anthony Minessale anthmct@yahoo.com
* Development of this app Sponsered/Funded by TAAN Softworks Corp
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*/
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <asterisk/pbx.h>
#include <asterisk/cdr.h>
#include <asterisk/module.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
static char *tdesc = "Fork The CDR into 2 separate entities.";
static char *app = "ForkCDR";
static char *synopsis =
"Forks the Call Data Record";
static char *descrip =
" ForkCDR(): Causes the Call Data Record to fork an additional\n"
"cdr record starting from the time of the fork call\n";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
static void ast_cdr_clone(struct ast_cdr *cdr) {
struct ast_cdr *newcdr = ast_cdr_alloc();
memcpy(newcdr,cdr,sizeof(struct ast_cdr));
ast_cdr_append(cdr,newcdr);
gettimeofday(&newcdr->start, NULL);
memset(&newcdr->answer, 0, sizeof(newcdr->answer));
ast_cdr_add_flag(cdr,AST_CDR_FLAG_CHILD|AST_CDR_FLAG_LOCKED);
}
static void ast_cdr_fork(struct ast_channel *chan) {
if(chan && chan->cdr) {
ast_cdr_clone(chan->cdr);
}
}
static int forkcdr_exec(struct ast_channel *chan, void *data)
{
int res=0;
struct localuser *u;
LOCAL_USER_ADD(u);
ast_cdr_fork(chan);
LOCAL_USER_REMOVE(u);
return res;
}
int unload_module(void)
{
STANDARD_HANGUP_LOCALUSERS;
return ast_unregister_application(app);
}
int load_module(void)
{
return ast_register_application(app, forkcdr_exec, synopsis, descrip);
}
char *description(void)
{
return tdesc;
}
int usecount(void)
{
int res;
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -1,146 +0,0 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* Execute arbitrary system commands
*
* Copyright (C) 1999-2005, Digium
*
* Mark Spencer <markster@digium.com>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*/
#include <asterisk/lock.h>
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <asterisk/pbx.h>
#include <asterisk/module.h>
#include <asterisk/adsi.h>
#include <asterisk/options.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
static char *tdesc = "Get ADSI CPE ID";
static char *app = "GetCPEID";
static char *synopsis = "Get ADSI CPE ID";
static char *descrip =
" GetCPEID: Obtains and displays ADSI CPE ID and other information in order\n"
"to properly setup zapata.conf for on-hook operations.\n"
"Returns -1 on hangup only.\n";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
static int cpeid_setstatus(struct ast_channel *chan, char *stuff[], int voice)
{
int justify[5] = { ADSI_JUST_CENT, ADSI_JUST_LEFT, ADSI_JUST_LEFT, ADSI_JUST_LEFT };
char *tmp[5];
int x;
for (x=0;x<4;x++)
tmp[x] = stuff[x];
tmp[4] = NULL;
return adsi_print(chan, tmp, justify, voice);
}
static int cpeid_exec(struct ast_channel *chan, void *idata)
{
int res=0;
struct localuser *u;
unsigned char cpeid[4];
int gotgeometry = 0;
int gotcpeid = 0;
int width, height, buttons;
char data[4][80];
char *stuff[4];
LOCAL_USER_ADD(u);
stuff[0] = data[0];
stuff[1] = data[1];
stuff[2] = data[2];
stuff[3] = data[3];
memset(data, 0, sizeof(data));
strncpy(stuff[0], "** CPE Info **", sizeof(data[0]) - 1);
strncpy(stuff[1], "Identifying CPE...", sizeof(data[1]) - 1);
strncpy(stuff[2], "Please wait...", sizeof(data[2]) - 1);
res = adsi_load_session(chan, NULL, 0, 1);
if (res > 0) {
cpeid_setstatus(chan, stuff, 0);
res = adsi_get_cpeid(chan, cpeid, 0);
if (res > 0) {
gotcpeid = 1;
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "Got CPEID of '%02x:%02x:%02x:%02x' on '%s'\n", cpeid[0], cpeid[1], cpeid[2], cpeid[3], chan->name);
}
if (res > -1) {
strncpy(stuff[1], "Measuring CPE...", sizeof(data[1]) - 1);
strncpy(stuff[2], "Please wait...", sizeof(data[2]) - 1);
cpeid_setstatus(chan, stuff, 0);
res = adsi_get_cpeinfo(chan, &width, &height, &buttons, 0);
if (res > -1) {
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "CPE has %d lines, %d columns, and %d buttons on '%s'\n", height, width, buttons, chan->name);
gotgeometry = 1;
}
}
if (res > -1) {
if (gotcpeid)
snprintf(stuff[1], sizeof(data[1]), "CPEID: %02x:%02x:%02x:%02x", cpeid[0], cpeid[1], cpeid[2], cpeid[3]);
else
strncpy(stuff[1], "CPEID Unknown", sizeof(data[1]) - 1);
if (gotgeometry)
snprintf(stuff[2], sizeof(data[2]), "Geom: %dx%d, %d buttons", width, height, buttons);
else
strncpy(stuff[2], "Geometry unknown", sizeof(data[2]) - 1);
strncpy(stuff[3], "Press # to exit", sizeof(data[3]) - 1);
cpeid_setstatus(chan, stuff, 1);
for(;;) {
res = ast_waitfordigit(chan, 1000);
if (res < 0)
break;
if (res == '#') {
res = 0;
break;
}
}
adsi_unload_session(chan);
}
}
LOCAL_USER_REMOVE(u);
return res;
}
int unload_module(void)
{
STANDARD_HANGUP_LOCALUSERS;
return ast_unregister_application(app);
}
int load_module(void)
{
return ast_register_application(app, cpeid_exec, synopsis, descrip);
}
char *description(void)
{
return tdesc;
}
int usecount(void)
{
int res;
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -1,224 +0,0 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* Group Manipulation Applications
*
* Copyright (c) 2004 Digium
*
* Mark Spencer <markster@digium.com>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/options.h>
#include <asterisk/channel.h>
#include <asterisk/pbx.h>
#include <asterisk/module.h>
#include <asterisk/utils.h>
static char *tdesc = "Group Management Routines";
static char *app_group_count = "GetGroupCount";
static char *app_group_set = "SetGroup";
static char *app_group_check = "CheckGroup";
static char *group_count_synopsis = "GetGroupCount([groupname][@category])";
static char *group_set_synopsis = "SetGroup(groupname[@category])";
static char *group_check_synopsis = "CheckGroup(max[@category])";
static char *group_count_descrip =
"GetGroupCount([group][@category])\n"
" Calculates the group count for the specified group, or uses\n"
"the current channel's group if not specifed (and non-empty).\n"
"Stores result in GROUPCOUNT. Always returns 0.\n";
static char *group_set_descrip =
"SetGroup(group)\n"
" Sets the channel group to the specified value. Equivalent to\n"
"SetVar(GROUP=group). Always returns 0.\n";
static char *group_check_descrip =
"CheckGroup(max)\n"
" Checks that the current number of total channels in the\n"
"current channel's group does not exceed 'max'. If the number\n"
"does not exceed 'max', we continue to the next step. If the\n"
"number does in fact exceed max, if priority n+101 exists, then\n"
"execution continues at that step, otherwise -1 is returned.\n";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
#define DEFAULT_CATEGORY "GROUP"
static int group_get_count(char *group, char *category)
{
struct ast_channel *chan;
int count = 0;
char *test;
if (group && !ast_strlen_zero(group)) {
chan = ast_channel_walk_locked(NULL);
while(chan) {
test = pbx_builtin_getvar_helper(chan, category);
if (test && !strcasecmp(test, group))
count++;
ast_mutex_unlock(&chan->lock);
chan = ast_channel_walk_locked(chan);
}
}
return count;
}
static int group_count_exec(struct ast_channel *chan, void *data)
{
int res=0;
int count;
struct localuser *u;
char *group=NULL;
char *cat = NULL;
char ret[80]="";
char tmp[256]="";
LOCAL_USER_ADD(u);
/* Check and parse arguments */
if (data && !ast_strlen_zero(data)) {
strncpy(tmp, data, sizeof(tmp) - 1);
group = tmp;
cat = strchr(tmp, '@');
if (cat) {
*cat = '\0';
cat++;
}
}
if (cat)
snprintf(ret, sizeof(ret), "GROUP_%s", cat);
else
strncpy(ret, DEFAULT_CATEGORY, sizeof(ret) - 1);
if (!group || ast_strlen_zero(group)) {
group = pbx_builtin_getvar_helper(chan, ret);
}
count = group_get_count(group, ret);
snprintf(ret, sizeof(ret), "%d", count);
pbx_builtin_setvar_helper(chan, "GROUPCOUNT", ret);
LOCAL_USER_REMOVE(u);
return res;
}
static int group_set_exec(struct ast_channel *chan, void *data)
{
int res=0;
struct localuser *u;
char ret[80] = "";
char tmp[256] = "";
char *cat=NULL, *group=NULL;
LOCAL_USER_ADD(u);
/* Check and parse arguments */
if (data && !ast_strlen_zero(data)) {
strncpy(tmp, data, sizeof(tmp) - 1);
group = tmp;
cat = strchr(tmp, '@');
if (cat) {
*cat = '\0';
cat++;
}
}
if (cat)
snprintf(ret, sizeof(ret), "GROUP_%s", cat);
else
strncpy(ret, DEFAULT_CATEGORY, sizeof(ret) - 1);
if (group && !ast_strlen_zero(group)) {
pbx_builtin_setvar_helper(chan, ret, group);
} else
ast_log(LOG_WARNING, "SetGroup requires an argument (group name)\n");
LOCAL_USER_REMOVE(u);
return res;
}
static int group_check_exec(struct ast_channel *chan, void *data)
{
int res=0;
int max, count;
struct localuser *u;
char ret[80] = "";
char tmp[256] = "";
char *cat, *group;
LOCAL_USER_ADD(u);
if (data && !ast_strlen_zero(data)) {
strncpy(tmp, data, sizeof(tmp) - 1);
group = tmp;
cat = strchr(tmp, '@');
if (cat) {
*cat = '\0';
cat++;
}
if ((sscanf((char *)tmp, "%i", &max) == 1) && (max > -1)) {
if (cat)
snprintf(ret, sizeof(ret), "GROUP_%s", cat);
else
strncpy(ret, DEFAULT_CATEGORY, sizeof(ret) - 1);
count = group_get_count(pbx_builtin_getvar_helper(chan, ret), ret);
if (count > max) {
if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 101, chan->callerid))
chan->priority += 100;
else
res = -1;
}
} else
ast_log(LOG_WARNING, "CheckGroup requires a positive integer argument (max)\n");
} else
ast_log(LOG_WARNING, "CheckGroup requires an argument(max)\n");
LOCAL_USER_REMOVE(u);
return res;
}
int unload_module(void)
{
int res;
STANDARD_HANGUP_LOCALUSERS;
res = ast_unregister_application(app_group_count);
res |= ast_unregister_application(app_group_set);
res |= ast_unregister_application(app_group_check);
return res;
}
int load_module(void)
{
int res;
res = ast_register_application(app_group_count, group_count_exec, group_count_synopsis, group_count_descrip);
res |= ast_register_application(app_group_set, group_set_exec, group_set_synopsis, group_set_descrip);
res |= ast_register_application(app_group_check, group_check_exec, group_check_synopsis, group_check_descrip);
return res;
}
char *description(void)
{
return tdesc;
}
int usecount(void)
{
int res;
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -1,169 +0,0 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* HasVoicemail application
* Changes Copyright (c) 2004 Todd Freeman <freeman@andrews.edu>
*
* 95% based on HasNewVoicemail by:
*
* Copyright (c) 2003 Tilghman Lesher. All rights reserved.
*
* Tilghman Lesher <asterisk-hasnewvoicemail-app@the-tilghman.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/types.h>
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <asterisk/pbx.h>
#include <asterisk/module.h>
#include <asterisk/lock.h>
#include <asterisk/utils.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <dirent.h>
#include "../astconf.h"
static char *tdesc = "Indicator for whether a voice mailbox has messages in a given folder.";
static char *app_hasvoicemail = "HasVoicemail";
static char *hasvoicemail_synopsis = "Conditionally branches to priority + 101";
static char *hasvoicemail_descrip =
"HasVoicemail(vmbox[@context][:folder][|varname])\n"
" Branches to priority + 101, if there is voicemail in folder indicated."
" Optionally sets <varname> to the number of messages in that folder."
" Assumes folder of INBOX if not specified.\n";
static char *app_hasnewvoicemail = "HasNewVoicemail";
static char *hasnewvoicemail_synopsis = "Conditionally branches to priority + 101";
static char *hasnewvoicemail_descrip =
"HasNewVoicemail(vmbox[@context][|varname])\n"
" Branches to priority + 101, if there is voicemail in folder INBOX."
" Optionally sets <varname> to the number of messages in that folder.\n";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
static int hasvoicemail_exec(struct ast_channel *chan, void *data)
{
int res=0;
struct localuser *u;
char vmpath[256], *temps, *input, *varname = NULL, *vmbox, *vmfolder = "INBOX", *context = "default";
DIR *vmdir;
struct dirent *vment;
int vmcount = 0;
if (!data) {
ast_log(LOG_WARNING, "HasVoicemail requires an argument (vm-box[@context][:folder]|varname)\n");
return -1;
}
LOCAL_USER_ADD(u);
input = ast_strdupa((char *)data);
if (input) {
temps = input;
if ((temps = strsep(&input, "|"))) {
if (input && !ast_strlen_zero(input))
varname = input;
input = temps;
}
if ((temps = strsep(&input, ":"))) {
if (input && !ast_strlen_zero(input))
vmfolder = input;
input = temps;
}
if ((vmbox = strsep(&input, "@")))
if (input && !ast_strlen_zero(input))
context = input;
if (!vmbox)
vmbox = input;
snprintf(vmpath,sizeof(vmpath), "%s/voicemail/%s/%s/%s", (char *)ast_config_AST_SPOOL_DIR, context, vmbox, vmfolder);
if (!(vmdir = opendir(vmpath))) {
ast_log(LOG_NOTICE, "Voice mailbox %s at %s does not exist\n", vmbox, vmpath);
} else {
/* No matter what the format of VM, there will always be a .txt file for each message. */
while ((vment = readdir(vmdir)))
if (!strncmp(vment->d_name + 7,".txt",4))
vmcount++;
closedir(vmdir);
}
/* Set the count in the channel variable */
if (varname) {
char tmp[12];
snprintf(tmp, sizeof(tmp), "%d", vmcount);
pbx_builtin_setvar_helper(chan, varname, tmp);
}
if (vmcount > 0) {
/* Branch to the next extension */
if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 101, chan->callerid)) {
chan->priority += 100;
} else
ast_log(LOG_WARNING, "VM box %s@%s has new voicemail, but extension %s, priority %d doesn't exist\n", vmbox, context, chan->exten, chan->priority + 101);
}
} else {
ast_log(LOG_ERROR, "Out of memory error\n");
}
LOCAL_USER_REMOVE(u);
return res;
}
int unload_module(void)
{
int res;
STANDARD_HANGUP_LOCALUSERS;
res = ast_unregister_application(app_hasvoicemail);
res |= ast_unregister_application(app_hasnewvoicemail);
return res;
}
int load_module(void)
{
int res;
res = ast_register_application(app_hasvoicemail, hasvoicemail_exec, hasvoicemail_synopsis, hasvoicemail_descrip);
res |= ast_register_application(app_hasnewvoicemail, hasvoicemail_exec, hasnewvoicemail_synopsis, hasnewvoicemail_descrip);
return res;
}
char *description(void)
{
return tdesc;
}
int usecount(void)
{
int res;
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -1,196 +0,0 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* Stream to an icecast server via ICES (see contrib/asterisk-ices.xml)
*
* Copyright (C) 1999, Mark Spencer
*
* Mark Spencer <markster@linux-support.net>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*/
#include <asterisk/lock.h>
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <asterisk/frame.h>
#include <asterisk/pbx.h>
#include <asterisk/module.h>
#include <asterisk/translate.h>
#include <string.h>
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/time.h>
#include <errno.h>
#include "../astconf.h"
#define ICES "/usr/bin/ices"
#define LOCAL_ICES "/usr/local/bin/ices"
static char *tdesc = "Encode and Stream via icecast and ices";
static char *app = "ICES";
static char *synopsis = "Encode and stream using 'ices'";
static char *descrip =
" ICES(config.xml) Streams to an icecast server using ices\n"
"(available separately). A configuration file must be supplied\n"
"for ices (see examples/asterisk-ices.conf). Returns -1 on\n"
"hangup or 0 otherwise.\n";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
static int icesencode(char *filename, int fd)
{
int res;
int x;
res = fork();
if (res < 0)
ast_log(LOG_WARNING, "Fork failed\n");
if (res)
return res;
dup2(fd, STDIN_FILENO);
for (x=STDERR_FILENO + 1;x<256;x++) {
if ((x != STDIN_FILENO) && (x != STDOUT_FILENO))
close(x);
}
/* Most commonly installed in /usr/local/bin */
execl(ICES, "ices", filename, (char *)NULL);
/* But many places has it in /usr/bin */
execl(LOCAL_ICES, "ices", filename, (char *)NULL);
/* As a last-ditch effort, try to use PATH */
execlp("ices", "ices", filename, (char *)NULL);
ast_log(LOG_WARNING, "Execute of ices failed\n");
return -1;
}
static int ices_exec(struct ast_channel *chan, void *data)
{
int res=0;
struct localuser *u;
int fds[2];
int ms = -1;
int pid = -1;
int flags;
int oreadformat;
struct timeval last;
struct ast_frame *f;
char filename[256]="";
char *c;
last.tv_usec = 0;
last.tv_sec = 0;
if (!data || !strlen(data)) {
ast_log(LOG_WARNING, "ICES requires an argument (configfile.xml)\n");
return -1;
}
if (pipe(fds)) {
ast_log(LOG_WARNING, "Unable to create pipe\n");
return -1;
}
flags = fcntl(fds[1], F_GETFL);
fcntl(fds[1], F_SETFL, flags | O_NONBLOCK);
LOCAL_USER_ADD(u);
ast_stopstream(chan);
if (chan->_state != AST_STATE_UP)
res = ast_answer(chan);
if (res) {
close(fds[0]);
close(fds[1]);
ast_log(LOG_WARNING, "Answer failed!\n");
return -1;
}
oreadformat = chan->readformat;
res = ast_set_read_format(chan, AST_FORMAT_SLINEAR);
if (res < 0) {
close(fds[0]);
close(fds[1]);
ast_log(LOG_WARNING, "Unable to set write format to signed linear\n");
return -1;
}
if (((char *)data)[0] == '/')
strncpy(filename, (char *)data, sizeof(filename) - 1);
else
snprintf(filename, sizeof(filename), "%s/%s", (char *)ast_config_AST_CONFIG_DIR, (char *)data);
/* Placeholder for options */
c = strchr(filename, '|');
if (c)
*c = '\0';
res = icesencode(filename, fds[0]);
close(fds[0]);
if (res >= 0) {
pid = res;
for (;;) {
/* Wait for audio, and stream */
ms = ast_waitfor(chan, -1);
if (ms < 0) {
ast_log(LOG_DEBUG, "Hangup detected\n");
res = -1;
break;
}
f = ast_read(chan);
if (!f) {
ast_log(LOG_DEBUG, "Null frame == hangup() detected\n");
res = -1;
break;
}
if (f->frametype == AST_FRAME_VOICE) {
res = write(fds[1], f->data, f->datalen);
if (res < 0) {
if (errno != EAGAIN) {
ast_log(LOG_WARNING, "Write failed to pipe: %s\n", strerror(errno));
res = -1;
break;
}
}
}
ast_frfree(f);
}
}
close(fds[1]);
LOCAL_USER_REMOVE(u);
if (pid > -1)
kill(pid, SIGKILL);
if (!res && oreadformat)
ast_set_read_format(chan, oreadformat);
return res;
}
int unload_module(void)
{
STANDARD_HANGUP_LOCALUSERS;
return ast_unregister_application(app);
}
int load_module(void)
{
return ast_register_application(app, ices_exec, synopsis, descrip);
}
char *description(void)
{
return tdesc;
}
int usecount(void)
{
int res;
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -1,89 +0,0 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* App to transmit an image
*
* Copyright (C) 1999, Mark Spencer
*
* Mark Spencer <markster@linux-support.net>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*/
#include <asterisk/lock.h>
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <asterisk/pbx.h>
#include <asterisk/module.h>
#include <asterisk/translate.h>
#include <asterisk/image.h>
#include <string.h>
#include <stdlib.h>
static char *tdesc = "Image Transmission Application";
static char *app = "SendImage";
static char *synopsis = "Send an image file";
static char *descrip =
" SendImage(filename): Sends an image on a channel. If the channel\n"
"does not support image transport, and there exists a step with\n"
"priority n + 101, then execution will continue at that step.\n"
"Otherwise, execution will continue at the next priority level.\n"
"SendImage only returns 0 if the image was sent correctly or if\n"
"the channel does not support image transport, and -1 otherwise.\n";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
static int sendimage_exec(struct ast_channel *chan, void *data)
{
int res = 0;
struct localuser *u;
if (!data || !strlen((char *)data)) {
ast_log(LOG_WARNING, "SendImage requires an argument (filename)\n");
return -1;
}
LOCAL_USER_ADD(u);
if (!ast_supports_images(chan)) {
/* Does not support transport */
if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 101, chan->callerid))
chan->priority += 100;
return 0;
}
res = ast_send_image(chan, data);
LOCAL_USER_REMOVE(u);
return res;
}
int unload_module(void)
{
STANDARD_HANGUP_LOCALUSERS;
return ast_unregister_application(app);
}
int load_module(void)
{
return ast_register_application(app, sendimage_exec, synopsis, descrip);
}
char *description(void)
{
return tdesc;
}
int usecount(void)
{
int res;
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -11,7 +11,6 @@
* the GNU General Public License
*/
#include <asterisk/lock.h>
#include <asterisk/file.h>
#include <asterisk/frame.h>
#include <asterisk/logger.h>
@@ -24,22 +23,12 @@
#include <sys/ioctl.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#include <sys/time.h>
#include <linux/soundcard.h>
#include <netinet/in.h>
#if defined(__linux__)
#include <linux/soundcard.h>
#elif defined(__FreeBSD__)
#include <sys/soundcard.h>
#else
#include <soundcard.h>
#endif
#ifdef __OpenBSD__
#define DEV_DSP "/dev/audio"
#else
#define DEV_DSP "/dev/dsp"
#endif
/* Number of 32 byte buffers -- each buffer is 2 ms */
#define BUFFER_SIZE 32
@@ -48,40 +37,34 @@ static char *tdesc = "Intercom using /dev/dsp for output";
static char *app = "Intercom";
static char *synopsis = "(Obsolete) Send to Intercom";
static char *descrip =
" Intercom(): Sends the user to the intercom (i.e. /dev/dsp). This program\n"
"is generally considered obselete by the chan_oss module. Returns 0 if the\n"
"user exits with a DTMF tone, or -1 if they hangup.\n";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
AST_MUTEX_DEFINE_STATIC(sound_lock);
static pthread_mutex_t sound_lock = PTHREAD_MUTEX_INITIALIZER;
static int sound = -1;
static int write_audio(short *data, int len)
{
int res;
struct audio_buf_info info;
ast_mutex_lock(&sound_lock);
pthread_mutex_lock(&sound_lock);
if (sound < 0) {
ast_log(LOG_WARNING, "Sound device closed?\n");
ast_mutex_unlock(&sound_lock);
pthread_mutex_unlock(&sound_lock);
return -1;
}
if (ioctl(sound, SNDCTL_DSP_GETOSPACE, &info)) {
ast_log(LOG_WARNING, "Unable to read output space\n");
ast_mutex_unlock(&sound_lock);
pthread_mutex_unlock(&sound_lock);
return -1;
}
res = write(sound, data, len);
ast_mutex_unlock(&sound_lock);
pthread_mutex_unlock(&sound_lock);
return res;
}
static int create_audio(void)
static int create_audio()
{
int fmt, desired, res, fd;
fd = open(DEV_DSP, O_WRONLY);
@@ -133,44 +116,48 @@ static int intercom_exec(struct ast_channel *chan, void *data)
int res = 0;
struct localuser *u;
struct ast_frame *f;
int oreadformat;
LOCAL_USER_ADD(u);
/* Remember original read format */
oreadformat = chan->readformat;
/* Set mode to signed linear */
res = ast_set_read_format(chan, AST_FORMAT_SLINEAR);
if (res < 0) {
ast_log(LOG_WARNING, "Unable to set format to signed linear on channel %s\n", chan->name);
struct ast_channel *trans;
if (!data) {
ast_log(LOG_WARNING, "Playback requires an argument (filename)\n");
return -1;
}
/* Read packets from the channel */
while(!res) {
res = ast_waitfor(chan, -1);
if (res > 0) {
res = 0;
f = ast_read(chan);
if (f) {
if (f->frametype == AST_FRAME_DTMF) {
LOCAL_USER_ADD(u);
/* See if we need a translator */
if (!(chan->format & AST_FORMAT_SLINEAR))
trans = ast_translator_create(chan, AST_FORMAT_SLINEAR, AST_DIRECTION_IN);
else
trans = chan;
if (trans) {
/* Read packets from the channel */
while(!res) {
res = ast_waitfor(trans, -1);
if (res > 0) {
res = 0;
f = ast_read(trans);
if (f) {
if (f->frametype == AST_FRAME_DTMF) {
ast_frfree(f);
break;
} else {
if (f->frametype == AST_FRAME_VOICE) {
if (f->subclass == AST_FORMAT_SLINEAR) {
res = write_audio(f->data, f->datalen);
if (res > 0)
res = 0;
} else
ast_log(LOG_DEBUG, "Unable to handle non-signed linear frame (%d)\n", f->subclass);
}
}
ast_frfree(f);
break;
} else {
if (f->frametype == AST_FRAME_VOICE) {
if (f->subclass == AST_FORMAT_SLINEAR) {
res = write_audio(f->data, f->datalen);
if (res > 0)
res = 0;
} else
ast_log(LOG_DEBUG, "Unable to handle non-signed linear frame (%d)\n", f->subclass);
}
}
ast_frfree(f);
} else
res = -1;
} else
res = -1;
}
}
}
if (trans != chan)
ast_translator_destroy(trans);
} else
ast_log(LOG_WARNING, "Unable to build translator to signed linear format on '%s'\n", chan->name);
LOCAL_USER_REMOVE(u);
if (!res)
ast_set_read_format(chan, oreadformat);
return res;
}
@@ -186,7 +173,7 @@ int load_module(void)
{
if (create_audio())
return -1;
return ast_register_application(app, intercom_exec, synopsis, descrip);
return ast_register_application(app, intercom_exec);
}
char *description(void)
@@ -200,8 +187,3 @@ int usecount(void)
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -1,114 +0,0 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* App to lookup the callerid number, and see if it is blacklisted
*
* Copyright (C) 1999, Mark Spencer
*
* Mark Spencer <markster@linux-support.net>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*/
#include <asterisk/lock.h>
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/options.h>
#include <asterisk/channel.h>
#include <asterisk/pbx.h>
#include <asterisk/module.h>
#include <asterisk/translate.h>
#include <asterisk/image.h>
#include <asterisk/callerid.h>
#include <asterisk/astdb.h>
#include <string.h>
#include <stdlib.h>
static char *tdesc = "Look up Caller*ID name/number from blacklist database";
static char *app = "LookupBlacklist";
static char *synopsis = "Look up Caller*ID name/number from blacklist database";
static char *descrip =
" LookupBlacklist: Looks up the Caller*ID number on the active\n"
"channel in the Asterisk database (family 'blacklist'). If the\n"
"number is found, and if there exists a priority n + 101,\n"
"where 'n' is the priority of the current instance, then the\n"
"channel will be setup to continue at that priority level.\n"
"Otherwise, it returns 0. Does nothing if no Caller*ID was received on the\n"
"channel.\n"
"Example: database put blacklist <name/number> 1\n";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
static int
lookupblacklist_exec (struct ast_channel *chan, void *data)
{
char old_cid[144] = "", *num, *name;
char blacklist[1];
char shrunknum[64] = "";
struct localuser *u;
int bl = 0;
LOCAL_USER_ADD (u);
if (chan->callerid)
{
strncpy (old_cid, chan->callerid, sizeof (old_cid) - 1);
ast_callerid_parse (old_cid, &name, &num);
if (num)
strncpy (shrunknum, num, sizeof (shrunknum) - 1);
else
num = shrunknum;
ast_shrink_phone_number (shrunknum);
if (!ast_db_get ("blacklist", shrunknum, blacklist, sizeof (blacklist)))
{
if (option_verbose > 2)
ast_log(LOG_NOTICE, "Blacklisted number %s found\n",shrunknum);
bl = 1;
}
else if (!ast_db_get ("blacklist", name, blacklist, sizeof (blacklist)))
{
if (option_verbose > 2)
ast_log (LOG_NOTICE,"Blacklisted name \"%s\" found\n",name);
bl = 1;
}
}
if (bl && ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 101, chan->callerid))
chan->priority+=100;
LOCAL_USER_REMOVE (u);
return 0;
}
int unload_module (void)
{
STANDARD_HANGUP_LOCALUSERS;
return ast_unregister_application (app);
}
int load_module (void)
{
return ast_register_application (app, lookupblacklist_exec, synopsis,descrip);
}
char *description (void)
{
return tdesc;
}
int usecount (void)
{
int res;
STANDARD_USECOUNT (res);
return res;
}
char *key ()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -1,111 +0,0 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* App to set callerid name from database, based on directory number
*
* Copyright (C) 1999, Mark Spencer
*
* Mark Spencer <markster@linux-support.net>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*/
#include <asterisk/lock.h>
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/options.h>
#include <asterisk/channel.h>
#include <asterisk/pbx.h>
#include <asterisk/module.h>
#include <asterisk/translate.h>
#include <asterisk/image.h>
#include <asterisk/callerid.h>
#include <asterisk/astdb.h>
#include <string.h>
#include <stdlib.h>
static char *tdesc = "Look up CallerID Name from local database";
static char *app = "LookupCIDName";
static char *synopsis = "Look up CallerID Name from local database";
static char *descrip =
" LookupCIDName: Looks up the Caller*ID number on the active\n"
"channel in the Asterisk database (family 'cidname') and sets the\n"
"Caller*ID name. Does nothing if no Caller*ID was received on the\n"
"channel. This is useful if you do not subscribe to Caller*ID\n"
"name delivery, or if you want to change the names on some incoming\n"
"calls. Always returns 0.\n";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
static int
lookupcidname_exec (struct ast_channel *chan, void *data)
{
char old_cid[144] = "", *num, *name;
char new_cid[144];
char dbname[64];
char shrunknum[64] = "";
struct localuser *u;
LOCAL_USER_ADD (u);
if (chan->callerid)
{
strncpy (old_cid, chan->callerid, sizeof (old_cid) - 1);
ast_callerid_parse (old_cid, &name, &num); /* this destroys the original string */
if (num) /* It's possible to get an empty number */
strncpy (shrunknum, num, sizeof (shrunknum) - 1);
else
num = shrunknum;
ast_shrink_phone_number (shrunknum);
if (!ast_db_get ("cidname", shrunknum, dbname, sizeof (dbname)))
{
snprintf (new_cid, sizeof (new_cid), "\"%s\" <%s>", dbname, num);
ast_set_callerid (chan, new_cid, 0);
if (option_verbose > 2)
ast_verbose (VERBOSE_PREFIX_3 "Changed Caller*ID to %s\n",
new_cid);
}
}
LOCAL_USER_REMOVE (u);
return 0;
}
int
unload_module (void)
{
STANDARD_HANGUP_LOCALUSERS;
return ast_unregister_application (app);
}
int
load_module (void)
{
return ast_register_application (app, lookupcidname_exec, synopsis,
descrip);
}
char *
description (void)
{
return tdesc;
}
int
usecount (void)
{
int res;
STANDARD_USECOUNT (res);
return res;
}
char *
key ()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -1,253 +0,0 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* Macro Implementation
*
* Copyright (C) 2003, Digium
*
* Mark Spencer <markster@digium.com>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*/
#include <sys/types.h>
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <asterisk/pbx.h>
#include <asterisk/module.h>
#include <asterisk/options.h>
#include <asterisk/utils.h>
#include <asterisk/lock.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#define MAX_ARGS 80
static char *tdesc = "Extension Macros";
static char *descrip =
" Macro(macroname|arg1|arg2...): Executes a macro using the context\n"
"'macro-<macroname>', jumping to the 's' extension of that context and\n"
"executing each step, then returning when the steps end. The calling\n"
"extension, context, and priority are stored in ${MACRO_EXTEN}, \n"
"${MACRO_CONTEXT} and ${MACRO_PRIORITY} respectively. Arguments become\n"
"${ARG1}, ${ARG2}, etc in the macro context. Macro returns -1 if\n"
"any step in the macro returns -1, and 0 otherwise. If you Goto out\n"
"of the Macro context, the Macro will terminate and control will be return\n"
"at the location of the Goto. Otherwise if ${MACRO_OFFSET} is set at\n"
"termination, Macro will attempt to continue at priority\n"
"MACRO_OFFSET + N + 1 if such a step exists, and N + 1 otherwise.\n";
static char *app = "Macro";
static char *synopsis = "Macro Implementation";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
static int macro_exec(struct ast_channel *chan, void *data)
{
char tmp[256] = "";
char *cur, *rest;
char *macro;
char fullmacro[80];
char varname[80];
char *oldargs[MAX_ARGS + 1] = { NULL, };
int argc, x;
int res=0;
char oldexten[256]="";
int oldpriority;
char pc[80];
char oldcontext[256] = "";
char *offsets;
int offset;
int setmacrocontext=0;
char *save_macro_exten;
char *save_macro_context;
char *save_macro_priority;
char *save_macro_offset;
if (!data || ast_strlen_zero(data)) {
ast_log(LOG_WARNING, "Invalid Macro incantation\n");
return 0;
}
strncpy(tmp, data, sizeof(tmp) - 1);
rest = tmp;
macro = strsep(&rest, "|");
if (!macro || ast_strlen_zero(macro)) {
ast_log(LOG_WARNING, "Invalid macro name specified\n");
return 0;
}
snprintf(fullmacro, sizeof(fullmacro), "macro-%s", macro);
if (!ast_exists_extension(chan, fullmacro, "s", 1, chan->callerid)) {
if (!ast_context_find(fullmacro))
ast_log(LOG_WARNING, "No such context '%s' for macro '%s'\n", fullmacro, macro);
else
ast_log(LOG_WARNING, "Context '%s' for macro '%s' lacks 's' extension, priority 1\n", fullmacro, macro);
return 0;
}
/* Save old info */
oldpriority = chan->priority;
strncpy(oldexten, chan->exten, sizeof(oldexten) - 1);
strncpy(oldcontext, chan->context, sizeof(oldcontext) - 1);
if (ast_strlen_zero(chan->macrocontext)) {
strncpy(chan->macrocontext, chan->context, sizeof(chan->macrocontext) - 1);
strncpy(chan->macroexten, chan->exten, sizeof(chan->macroexten) - 1);
chan->macropriority = chan->priority;
setmacrocontext=1;
}
argc = 1;
/* Save old macro variables */
save_macro_exten = pbx_builtin_getvar_helper(chan, "MACRO_EXTEN");
if (save_macro_exten) save_macro_exten = strdup(save_macro_exten);
pbx_builtin_setvar_helper(chan, "MACRO_EXTEN", oldexten);
save_macro_context = pbx_builtin_getvar_helper(chan, "MACRO_CONTEXT");
if (save_macro_context) save_macro_context = strdup(save_macro_context);
pbx_builtin_setvar_helper(chan, "MACRO_CONTEXT", oldcontext);
save_macro_priority = pbx_builtin_getvar_helper(chan, "MACRO_PRIORITY");
if (save_macro_priority) save_macro_priority = strdup(save_macro_priority);
snprintf(pc, sizeof(pc), "%d", oldpriority);
pbx_builtin_setvar_helper(chan, "MACRO_PRIORITY", pc);
save_macro_offset = pbx_builtin_getvar_helper(chan, "MACRO_OFFSET");
if (save_macro_offset) save_macro_offset = strdup(save_macro_offset);
pbx_builtin_setvar_helper(chan, "MACRO_OFFSET", NULL);
/* Setup environment for new run */
chan->exten[0] = 's';
chan->exten[1] = '\0';
strncpy(chan->context, fullmacro, sizeof(chan->context) - 1);
chan->priority = 1;
while((cur = strsep(&rest, "|")) && (argc < MAX_ARGS)) {
/* Save copy of old arguments if we're overwriting some, otherwise
let them pass through to the other macro */
snprintf(varname, sizeof(varname), "ARG%d", argc);
oldargs[argc] = pbx_builtin_getvar_helper(chan, varname);
if (oldargs[argc])
oldargs[argc] = strdup(oldargs[argc]);
pbx_builtin_setvar_helper(chan, varname, cur);
argc++;
}
while(ast_exists_extension(chan, chan->context, chan->exten, chan->priority, chan->callerid)) {
if ((res = ast_spawn_extension(chan, chan->context, chan->exten, chan->priority, chan->callerid))) {
/* Something bad happened, or a hangup has been requested. */
if (((res >= '0') && (res <= '9')) || ((res >= 'A') && (res <= 'F')) ||
(res == '*') || (res == '#')) {
/* Just return result as to the previous application as if it had been dialed */
ast_log(LOG_DEBUG, "Oooh, got something to jump out with ('%c')!\n", res);
break;
}
switch(res) {
case AST_PBX_KEEPALIVE:
if (option_debug)
ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited KEEPALIVE in macro %s on '%s'\n", chan->context, chan->exten, chan->priority, macro, chan->name);
else if (option_verbose > 1)
ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited KEEPALIVE in macro '%s' on '%s'\n", chan->context, chan->exten, chan->priority, macro, chan->name);
goto out;
break;
default:
if (option_debug)
ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited non-zero on '%s' in macro '%s'\n", chan->context, chan->exten, chan->priority, chan->name, macro);
else if (option_verbose > 1)
ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited non-zero on '%s' in macro '%s'\n", chan->context, chan->exten, chan->priority, chan->name, macro);
goto out;
}
}
if (strcasecmp(chan->context, fullmacro)) {
if (option_verbose > 1)
ast_verbose(VERBOSE_PREFIX_2 "Channel '%s' jumping out of macro '%s'\n", chan->name, macro);
break;
}
/* don't stop executing extensions when we're in "h" */
if (chan->_softhangup && strcasecmp(oldexten,"h")) {
ast_log(LOG_DEBUG, "Extension %s, priority %d returned normally even though call was hung up\n",
chan->exten, chan->priority);
goto out;
}
chan->priority++;
}
out:
for (x=1;x<argc;x++) {
/* Restore old arguments and delete ours */
snprintf(varname, sizeof(varname), "ARG%d", x);
if (oldargs[x]) {
pbx_builtin_setvar_helper(chan, varname, oldargs[x]);
free(oldargs[x]);
} else {
pbx_builtin_setvar_helper(chan, varname, NULL);
}
}
/* Restore macro variables */
pbx_builtin_setvar_helper(chan, "MACRO_EXTEN", save_macro_exten);
if (save_macro_exten) free(save_macro_exten);
pbx_builtin_setvar_helper(chan, "MACRO_CONTEXT", save_macro_context);
if (save_macro_context) free(save_macro_context);
pbx_builtin_setvar_helper(chan, "MACRO_PRIORITY", save_macro_priority);
if (save_macro_priority) free(save_macro_priority);
if (setmacrocontext) {
chan->macrocontext[0] = '\0';
chan->macroexten[0] = '\0';
chan->macropriority = 0;
}
if (!strcasecmp(chan->context, fullmacro)) {
/* If we're leaving the macro normally, restore original information */
chan->priority = oldpriority;
strncpy(chan->context, oldcontext, sizeof(chan->context) - 1);
if (!(chan->_softhangup & AST_SOFTHANGUP_ASYNCGOTO)) {
/* Copy the extension, so long as we're not in softhangup, where we could be given an asyncgoto */
strncpy(chan->exten, oldexten, sizeof(chan->exten) - 1);
if ((offsets = pbx_builtin_getvar_helper(chan, "MACRO_OFFSET"))) {
/* Handle macro offset if it's set by checking the availability of step n + offset + 1, otherwise continue
normally if there is any problem */
if (sscanf(offsets, "%d", &offset) == 1) {
if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + offset + 1, chan->callerid)) {
chan->priority += offset;
}
}
}
}
}
pbx_builtin_setvar_helper(chan, "MACRO_OFFSET", save_macro_offset);
if (save_macro_offset) free(save_macro_offset);
return res;
}
int unload_module(void)
{
STANDARD_HANGUP_LOCALUSERS;
return ast_unregister_application(app);
}
int load_module(void)
{
return ast_register_application(app, macro_exec, synopsis, descrip);
}
char *description(void)
{
return tdesc;
}
int usecount(void)
{
int res;
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,148 +0,0 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* Digital Milliwatt Test
*
* Copyright (C) 2002, Mark Spencer
*
* Mark Spencer <markster@linux-support.net>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*/
#include <asterisk/lock.h>
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <asterisk/pbx.h>
#include <asterisk/module.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
static char *tdesc = "Digital Milliwatt (mu-law) Test Application";
static char *app = "Milliwatt";
static char *synopsis = "Generate a Constant 1000Hz tone at 0dbm (mu-law)";
static char *descrip =
"Milliwatt(): Generate a Constant 1000Hz tone at 0dbm (mu-law)\n";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
static char digital_milliwatt[] = {0x1e,0x0b,0x0b,0x1e,0x9e,0x8b,0x8b,0x9e} ;
static void *milliwatt_alloc(struct ast_channel *chan, void *params)
{
int *indexp;
indexp = malloc(sizeof(int));
if (indexp == NULL) return(NULL);
*indexp = 0;
return(indexp);
}
static void milliwatt_release(struct ast_channel *chan, void *data)
{
free(data);
return;
}
static int milliwatt_generate(struct ast_channel *chan, void *data, int len, int samples)
{
struct ast_frame wf;
unsigned char waste[AST_FRIENDLY_OFFSET];
unsigned char buf[640];
int i,*indexp = (int *) data;
if (len > sizeof(buf))
{
ast_log(LOG_WARNING,"Only doing %d bytes (%d bytes requested)\n",(int)sizeof(buf),len);
len = sizeof(buf);
}
waste[0] = 0; /* make compiler happy */
wf.frametype = AST_FRAME_VOICE;
wf.subclass = AST_FORMAT_ULAW;
wf.offset = AST_FRIENDLY_OFFSET;
wf.mallocd = 0;
wf.data = buf;
wf.datalen = len;
wf.samples = wf.datalen;
wf.src = "app_milliwatt";
wf.delivery.tv_sec = 0;
wf.delivery.tv_usec = 0;
/* create a buffer containing the digital milliwatt pattern */
for(i = 0; i < len; i++)
{
buf[i] = digital_milliwatt[(*indexp)++];
*indexp &= 7;
}
if (ast_write(chan,&wf) < 0)
{
ast_log(LOG_WARNING,"Failed to write frame to '%s': %s\n",chan->name,strerror(errno));
return -1;
}
return 0;
}
static struct ast_generator milliwattgen =
{
alloc: milliwatt_alloc,
release: milliwatt_release,
generate: milliwatt_generate,
} ;
static int milliwatt_exec(struct ast_channel *chan, void *data)
{
struct localuser *u;
LOCAL_USER_ADD(u);
ast_set_write_format(chan, AST_FORMAT_ULAW);
ast_set_read_format(chan, AST_FORMAT_ULAW);
if (chan->_state != AST_STATE_UP)
{
ast_answer(chan);
}
if (ast_activate_generator(chan,&milliwattgen,"milliwatt") < 0)
{
ast_log(LOG_WARNING,"Failed to activate generator on '%s'\n",chan->name);
return -1;
}
while(!ast_safe_sleep(chan, 10000));
ast_deactivate_generator(chan);
LOCAL_USER_REMOVE(u);
return -1;
}
int unload_module(void)
{
STANDARD_HANGUP_LOCALUSERS;
return ast_unregister_application(app);
}
int load_module(void)
{
return ast_register_application(app, milliwatt_exec, synopsis, descrip);
}
char *description(void)
{
return tdesc;
}
int usecount(void)
{
int res;
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -3,15 +3,14 @@
*
* Silly application to play an MP3 file -- uses mpg123
*
* Copyright (C) 1999-2004, Digium, Inc.
* Copyright (C) 1999, Mark Spencer
*
* Mark Spencer <markster@digium.com>
* Mark Spencer <markster@linux-support.net>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*/
#include <asterisk/lock.h>
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
@@ -25,22 +24,15 @@
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <pthread.h>
#include <sys/time.h>
#define LOCAL_MPG_123 "/usr/local/bin/mpg123"
#define MPG_123 "/usr/bin/mpg123"
static char *tdesc = "Silly MP3 Application";
static char *app = "MP3Player";
static char *synopsis = "Play an MP3 file or stream";
static char *descrip =
" MP3Player(location) Executes mpg123 to play the given location\n"
"which typically would be a filename or a URL. Returns -1 on\n"
"hangup or 0 otherwise. User can exit by pressing any key\n.";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
@@ -48,69 +40,41 @@ LOCAL_USER_DECL;
static int mp3play(char *filename, int fd)
{
int res;
int x;
res = fork();
if (res < 0)
ast_log(LOG_WARNING, "Fork failed\n");
if (res)
return res;
dup2(fd, STDOUT_FILENO);
for (x=0;x<256;x++) {
if (x != STDOUT_FILENO)
close(x);
}
/* Execute mpg123, but buffer if it's a net connection */
if (!strncasecmp(filename, "http://", 7)) {
/* Most commonly installed in /usr/local/bin */
execl(LOCAL_MPG_123, "mpg123", "-q", "-s", "-b", "1024", "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL);
/* But many places has it in /usr/bin */
execl(MPG_123, "mpg123", "-q", "-s", "-b", "1024","-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL);
/* As a last-ditch effort, try to use PATH */
execlp("mpg123", "mpg123", "-q", "-s", "-b", "1024", "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL);
}
else {
/* Most commonly installed in /usr/local/bin */
execl(MPG_123, "mpg123", "-q", "-s", "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL);
/* But many places has it in /usr/bin */
execl(LOCAL_MPG_123, "mpg123", "-q", "-s", "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL);
/* As a last-ditch effort, try to use PATH */
execlp("mpg123", "mpg123", "-q", "-s", "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL);
}
if (strncmp(filename, "http://", 7))
execl(MPG_123, MPG_123, "-q", "-s", "-b", "1024", "--mono", "-r", "8000", filename, NULL);
else
execl(MPG_123, MPG_123, "-q", "-s", "--mono", "-r", "8000", filename, NULL);
ast_log(LOG_WARNING, "Execute of mpg123 failed\n");
return -1;
}
static int timed_read(int fd, void *data, int datalen, int timeout)
{
int res;
struct pollfd fds[1];
fds[0].fd = fd;
fds[0].events = POLLIN;
res = poll(fds, 1, timeout);
if (res < 1) {
ast_log(LOG_NOTICE, "Poll timed out/errored out with %d\n", res);
return -1;
}
return read(fd, data, datalen);
}
static int mp3_exec(struct ast_channel *chan, void *data)
{
int res=0;
struct localuser *u;
struct ast_channel *trans;
int fds[2];
int rfds[2];
int ms = -1;
int pid = -1;
int owriteformat;
int timeout = 2000;
struct timeval now, next;
int pid;
int us;
struct timeval tv;
struct timeval last;
struct ast_frame *f;
struct myframe {
struct ast_frame f;
char offset[AST_FRIENDLY_OFFSET];
short frdata[160];
char frdata[160];
} myf;
last.tv_usec = 0;
last.tv_sec = 0;
if (!data) {
ast_log(LOG_WARNING, "MP3 Playback requires an argument (filename)\n");
return -1;
@@ -121,81 +85,28 @@ static int mp3_exec(struct ast_channel *chan, void *data)
}
LOCAL_USER_ADD(u);
ast_stopstream(chan);
owriteformat = chan->writeformat;
res = ast_set_write_format(chan, AST_FORMAT_SLINEAR);
if (res < 0) {
ast_log(LOG_WARNING, "Unable to set write format to signed linear\n");
return -1;
}
gettimeofday(&now, NULL);
res = mp3play((char *)data, fds[1]);
if (!strncasecmp((char *)data, "http://", 7)) {
timeout = 10000;
}
/* Wait 1000 ms first */
next = now;
next.tv_sec += 1;
if (res >= 0) {
pid = res;
/* Order is important -- there's almost always going to be mp3... we want to prioritize the
user */
for (;;) {
gettimeofday(&now, NULL);
ms = (next.tv_sec - now.tv_sec) * 1000;
ms += (next.tv_usec - now.tv_usec) / 1000;
#if 0
printf("ms: %d\n", ms);
#endif
if (ms <= 0) {
#if 0
{
static struct timeval last;
struct timeval tv;
gettimeofday(&tv, NULL);
printf("Since last: %ld\n", (tv.tv_sec - last.tv_sec) * 1000 + (tv.tv_usec - last.tv_usec) / 1000);
last = tv;
}
#endif
res = timed_read(fds[0], myf.frdata, sizeof(myf.frdata), timeout);
if (res > 0) {
myf.f.frametype = AST_FRAME_VOICE;
myf.f.subclass = AST_FORMAT_SLINEAR;
myf.f.datalen = res;
myf.f.samples = res / 2;
myf.f.mallocd = 0;
myf.f.offset = AST_FRIENDLY_OFFSET;
myf.f.src = __PRETTY_FUNCTION__;
myf.f.delivery.tv_sec = 0;
myf.f.delivery.tv_usec = 0;
myf.f.data = myf.frdata;
if (ast_write(chan, &myf.f) < 0) {
res = -1;
break;
}
} else {
ast_log(LOG_DEBUG, "No more mp3\n");
res = 0;
break;
}
next.tv_usec += res / 2 * 125;
if (next.tv_usec >= 1000000) {
next.tv_usec -= 1000000;
next.tv_sec++;
}
#if 0
printf("Next: %d\n", ms);
#endif
} else {
ms = ast_waitfor(chan, ms);
if (ms < 0) {
if (chan->format & AST_FORMAT_SLINEAR)
trans = chan;
else
trans = ast_translator_create(chan, AST_FORMAT_SLINEAR, AST_DIRECTION_OUT);
if (trans) {
res = mp3play((char *)data, fds[1]);
if (res >= 0) {
pid = res;
/* Order is important -- there's almost always going to be mp3... we want to prioritize the
user */
rfds[0] = trans->fd;
rfds[1] = fds[0];
for (;;) {
CHECK_BLOCKING(trans);
res = ast_waitfor_n_fd(rfds, 2, &ms);
trans->blocking = 0;
if (res < 1) {
ast_log(LOG_DEBUG, "Hangup detected\n");
res = -1;
break;
}
if (ms) {
f = ast_read(chan);
} else if (res == trans->fd) {
f = ast_read(trans);
if (!f) {
ast_log(LOG_DEBUG, "Null frame == hangup() detected\n");
res = -1;
@@ -208,17 +119,53 @@ static int mp3_exec(struct ast_channel *chan, void *data)
break;
}
ast_frfree(f);
}
} else if (res == fds[0]) {
gettimeofday(&tv, NULL);
if (last.tv_sec || last.tv_usec) {
/* We should wait at least a frame length */
us = sizeof(myf.frdata) / 16 * 1000;
/* Subtract 1,000,000 us for each second late we've passed */
us -= (tv.tv_sec - last.tv_sec) * 1000000;
/* And one for each us late we've passed */
us -= (tv.tv_usec - last.tv_usec);
/* Sleep that long if needed */
if (us > 0)
usleep(us);
}
last = tv;
res = read(fds[0], myf.frdata, sizeof(myf.frdata));
if (res > 0) {
myf.f.frametype = AST_FRAME_VOICE;
myf.f.subclass = AST_FORMAT_SLINEAR;
myf.f.datalen = res;
myf.f.timelen = res / 16;
myf.f.mallocd = 0;
myf.f.offset = AST_FRIENDLY_OFFSET;
myf.f.src = __PRETTY_FUNCTION__;
myf.f.data = myf.frdata;
if (ast_write(trans, &myf.f) < 0) {
res = -1;
break;
}
} else {
ast_log(LOG_DEBUG, "No more mp3\n");
res = 0;
}
} else {
ast_log(LOG_DEBUG, "HuhHHH?\n");
res = -1;
break;
}
}
kill(pid, SIGTERM);
}
}
if (trans != chan)
ast_translator_destroy(trans);
} else
ast_log(LOG_WARNING, "No translator channel available\n");
close(fds[0]);
close(fds[1]);
LOCAL_USER_REMOVE(u);
if (pid > -1)
kill(pid, SIGKILL);
if (!res && owriteformat)
ast_set_write_format(chan, owriteformat);
return res;
}
@@ -230,7 +177,7 @@ int unload_module(void)
int load_module(void)
{
return ast_register_application(app, mp3_exec, synopsis, descrip);
return ast_register_application(app, mp3_exec);
}
char *description(void)
@@ -244,8 +191,3 @@ int usecount(void)
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -1,229 +0,0 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* Silly application to play an NBScat file -- uses nbscat8k
*
* Copyright (C) 1999, Mark Spencer
*
* Mark Spencer <markster@linux-support.net>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*/
#include <asterisk/lock.h>
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <asterisk/frame.h>
#include <asterisk/pbx.h>
#include <asterisk/module.h>
#include <asterisk/translate.h>
#include <string.h>
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/time.h>
#include <sys/socket.h>
#define LOCAL_NBSCAT "/usr/local/bin/nbscat8k"
#define NBSCAT "/usr/bin/nbscat8k"
static char *tdesc = "Silly NBS Stream Application";
static char *app = "NBScat";
static char *synopsis = "Play an NBS local stream";
static char *descrip =
" NBScat: Executes nbscat to listen to the local NBS stream.\n"
"Returns -1 on\n hangup or 0 otherwise. User can exit by \n"
"pressing any key\n.";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
static int NBScatplay(int fd)
{
int res;
int x;
res = fork();
if (res < 0)
ast_log(LOG_WARNING, "Fork failed\n");
if (res)
return res;
dup2(fd, STDOUT_FILENO);
for (x=0;x<256;x++) {
if (x != STDOUT_FILENO)
close(x);
}
/* Most commonly installed in /usr/local/bin */
execl(NBSCAT, "nbscat8k", "-d", (char *)NULL);
execl(LOCAL_NBSCAT, "nbscat8k", "-d", (char *)NULL);
ast_log(LOG_WARNING, "Execute of nbscat8k failed\n");
return -1;
}
static int timed_read(int fd, void *data, int datalen)
{
int res;
struct pollfd fds[1];
fds[0].fd = fd;
fds[0].events = POLLIN;
res = poll(fds, 1, 2000);
if (res < 1) {
ast_log(LOG_NOTICE, "Selected timed out/errored out with %d\n", res);
return -1;
}
return read(fd, data, datalen);
}
static int NBScat_exec(struct ast_channel *chan, void *data)
{
int res=0;
struct localuser *u;
int fds[2];
int ms = -1;
int pid = -1;
int owriteformat;
struct timeval now, next;
struct ast_frame *f;
struct myframe {
struct ast_frame f;
char offset[AST_FRIENDLY_OFFSET];
short frdata[160];
} myf;
if (socketpair(AF_LOCAL, SOCK_STREAM, 0, fds)) {
ast_log(LOG_WARNING, "Unable to create socketpair\n");
return -1;
}
LOCAL_USER_ADD(u);
ast_stopstream(chan);
owriteformat = chan->writeformat;
res = ast_set_write_format(chan, AST_FORMAT_SLINEAR);
if (res < 0) {
ast_log(LOG_WARNING, "Unable to set write format to signed linear\n");
return -1;
}
res = NBScatplay(fds[1]);
/* Wait 1000 ms first */
next = now;
next.tv_sec += 1;
if (res >= 0) {
pid = res;
/* Order is important -- there's almost always going to be mp3... we want to prioritize the
user */
for (;;) {
gettimeofday(&now, NULL);
ms = (next.tv_sec - now.tv_sec) * 1000;
ms += (next.tv_usec - now.tv_usec) / 1000;
#if 0
printf("ms: %d\n", ms);
#endif
if (ms <= 0) {
#if 0
{
static struct timeval last;
struct timeval tv;
gettimeofday(&tv, NULL);
printf("Since last: %ld\n", (tv.tv_sec - last.tv_sec) * 1000 + (tv.tv_usec - last.tv_usec) / 1000);
last = tv;
}
#endif
res = timed_read(fds[0], myf.frdata, sizeof(myf.frdata));
if (res > 0) {
myf.f.frametype = AST_FRAME_VOICE;
myf.f.subclass = AST_FORMAT_SLINEAR;
myf.f.datalen = res;
myf.f.samples = res / 2;
myf.f.mallocd = 0;
myf.f.offset = AST_FRIENDLY_OFFSET;
myf.f.src = __PRETTY_FUNCTION__;
myf.f.delivery.tv_sec = 0;
myf.f.delivery.tv_usec = 0;
myf.f.data = myf.frdata;
if (ast_write(chan, &myf.f) < 0) {
res = -1;
break;
}
} else {
ast_log(LOG_DEBUG, "No more mp3\n");
res = 0;
break;
}
next.tv_usec += res / 2 * 125;
if (next.tv_usec >= 1000000) {
next.tv_usec -= 1000000;
next.tv_sec++;
}
#if 0
printf("Next: %d\n", ms);
#endif
} else {
ms = ast_waitfor(chan, ms);
if (ms < 0) {
ast_log(LOG_DEBUG, "Hangup detected\n");
res = -1;
break;
}
if (ms) {
f = ast_read(chan);
if (!f) {
ast_log(LOG_DEBUG, "Null frame == hangup() detected\n");
res = -1;
break;
}
if (f->frametype == AST_FRAME_DTMF) {
ast_log(LOG_DEBUG, "User pressed a key\n");
ast_frfree(f);
res = 0;
break;
}
ast_frfree(f);
}
}
}
}
close(fds[0]);
close(fds[1]);
LOCAL_USER_REMOVE(u);
if (pid > -1)
kill(pid, SIGKILL);
if (!res && owriteformat)
ast_set_write_format(chan, owriteformat);
return res;
}
int unload_module(void)
{
STANDARD_HANGUP_LOCALUSERS;
return ast_unregister_application(app);
}
int load_module(void)
{
return ast_register_application(app, NBScat_exec, synopsis, descrip);
}
char *description(void)
{
return tdesc;
}
int usecount(void)
{
int res;
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -1,277 +0,0 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* Time of day - Report the time of day
*
* Copyright (C) 1999, Mark Spencer
*
* Mark Spencer <markster@linux-support.net>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*/
#include <asterisk/lock.h>
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <asterisk/pbx.h>
#include <asterisk/options.h>
#include <asterisk/config.h>
#include <asterisk/module.h>
#include <asterisk/utils.h>
#include <asterisk/causes.h>
#include <asterisk/astosp.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
static char *tdesc = "OSP Lookup";
static char *app = "OSPLookup";
static char *app2 = "OSPNext";
static char *app3 = "OSPFinish";
static char *synopsis = "Lookup number in OSP";
static char *synopsis2 = "Lookup next OSP entry";
static char *synopsis3 = "Record OSP entry";
static char *descrip =
" OSPLookup(exten[|provider[|options]]): Looks up an extension via OSP and sets\n"
"the variables, where 'n' is the number of the result beginning with 1:\n"
" ${OSPTECH}: The technology to use for the call\n"
" ${OSPDEST}: The destination to use for the call\n"
" ${OSPTOKEN}: The actual OSP token as a string\n"
" ${OSPHANDLE}: The OSP Handle for anything remaining\n"
" ${OSPRESULTS}: The number of OSP results total remaining\n"
"\n"
"If the lookup was *not* successful and there exists a priority n + 101,\n"
"then that priority will be taken next.\n" ;
static char *descrip2 =
" OSPNext: Looks up the next OSP Destination for ${OSPHANDLE}\n"
"See OSPLookup for more information\n"
"\n"
"If the lookup was *not* successful and there exists a priority n + 101,\n"
"then that priority will be taken next.\n" ;
static char *descrip3 =
" OSPFinish(status): Records call state for ${OSPHANDLE}, according to\n"
"status, which should be one of BUSY, CONGESTION, ANSWER, NOANSWER, or NOCHANAVAIL\n"
"or coincidentally, just what the Dial application stores in its ${DIALSTATUS}\n"
"\n"
"If the finishing was *not* successful and there exists a priority n + 101,\n"
"then that priority will be taken next.\n" ;
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
static int str2cause(char *cause)
{
if (!strcasecmp(cause, "BUSY"))
return AST_CAUSE_BUSY;
if (!strcasecmp(cause, "CONGESTION"))
return AST_CAUSE_CONGESTION;
if (!strcasecmp(cause, "ANSWER"))
return AST_CAUSE_NORMAL;
if (!strcasecmp(cause, "CANCEL"))
return AST_CAUSE_NORMAL;
if (!strcasecmp(cause, "NOANSWER"))
return AST_CAUSE_NOANSWER;
if (!strcasecmp(cause, "NOCHANAVAIL"))
return AST_CAUSE_CONGESTION;
ast_log(LOG_WARNING, "Unknown cause '%s', using NORMAL\n", cause);
return AST_CAUSE_NORMAL;
}
static int osplookup_exec(struct ast_channel *chan, void *data)
{
int res=0;
struct localuser *u;
char *temp;
char *provider, *opts=NULL;
struct ast_osp_result result;
if (!data || ast_strlen_zero(data) || !(temp = ast_strdupa(data))) {
ast_log(LOG_WARNING, "OSPLookup requires an argument (extension)\n");
return -1;
}
provider = strchr(temp, '|');
if (provider) {
*provider = '\0';
provider++;
opts = strchr(provider, '|');
if (opts) {
*opts = '\0';
opts++;
}
}
LOCAL_USER_ADD(u);
ast_log(LOG_DEBUG, "Whoo hoo, looking up OSP on '%s' via '%s'\n", temp, provider ? provider : "<default>");
if ((res = ast_osp_lookup(chan, provider, temp, chan->callerid, &result)) > 0) {
char tmp[80];
snprintf(tmp, sizeof(tmp), "%d", result.handle);
pbx_builtin_setvar_helper(chan, "OSPHANDLE", tmp);
pbx_builtin_setvar_helper(chan, "OSPTECH", result.tech);
pbx_builtin_setvar_helper(chan, "OSPDEST", result.dest);
pbx_builtin_setvar_helper(chan, "OSPTOKEN", result.token);
snprintf(tmp, sizeof(tmp), "%d", result.numresults);
pbx_builtin_setvar_helper(chan, "OSPRESULTS", tmp);
} else {
if (!res)
ast_log(LOG_NOTICE, "OSP Lookup failed for '%s' (provider '%s')\n", temp, provider ? provider : "<default>");
else
ast_log(LOG_DEBUG, "Got hangup on '%s' while doing OSP Lookup for '%s' (provider '%s')!\n", chan->name, temp, provider ? provider : "<default>" );
}
if (!res) {
/* Look for a "busy" place */
if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 101, chan->callerid))
chan->priority += 100;
} else if (res > 0)
res = 0;
LOCAL_USER_REMOVE(u);
return res;
}
static int ospnext_exec(struct ast_channel *chan, void *data)
{
int res=0;
struct localuser *u;
char *temp;
int cause;
struct ast_osp_result result;
if (!data || ast_strlen_zero(data)) {
ast_log(LOG_WARNING, "OSPNext should have an argument (cause)\n");
}
LOCAL_USER_ADD(u);
cause = str2cause((char *)data);
temp = pbx_builtin_getvar_helper(chan, "OSPHANDLE");
result.handle = -1;
if (temp && strlen(temp) && (sscanf(temp, "%i", &result.handle) == 1) && (result.handle > -1)) {
if ((res = ast_osp_next(&result, cause)) > 0) {
char tmp[80];
snprintf(tmp, sizeof(tmp), "%d", result.handle);
pbx_builtin_setvar_helper(chan, "OSPHANDLE", tmp);
pbx_builtin_setvar_helper(chan, "OSPTECH", result.tech);
pbx_builtin_setvar_helper(chan, "OSPDEST", result.dest);
pbx_builtin_setvar_helper(chan, "OSPTOKEN", result.token);
snprintf(tmp, sizeof(tmp), "%d", result.numresults);
pbx_builtin_setvar_helper(chan, "OSPRESULTS", tmp);
}
} else {
if (!res) {
if (result.handle < 0)
ast_log(LOG_NOTICE, "OSP Lookup Next failed for handle '%d'\n", result.handle);
else
ast_log(LOG_DEBUG, "No OSP handle specified\n");
} else
ast_log(LOG_DEBUG, "Got hangup on '%s' while doing OSP Next!\n", chan->name);
}
if (!res) {
/* Look for a "busy" place */
if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 101, chan->callerid))
chan->priority += 100;
} else if (res > 0)
res = 0;
LOCAL_USER_REMOVE(u);
return res;
}
static int ospfinished_exec(struct ast_channel *chan, void *data)
{
int res=0;
struct localuser *u;
char *temp;
int cause;
time_t start=0, duration=0;
struct ast_osp_result result;
if (!data || ast_strlen_zero(data)) {
ast_log(LOG_WARNING, "OSPFinish should have an argument (cause)\n");
}
if (chan->cdr) {
start = chan->cdr->answer.tv_sec;
if (start)
duration = time(NULL) - start;
else
duration = 0;
} else
ast_log(LOG_WARNING, "OSPFinish called on channel '%s' with no CDR!\n", chan->name);
LOCAL_USER_ADD(u);
cause = str2cause((char *)data);
temp = pbx_builtin_getvar_helper(chan, "OSPHANDLE");
result.handle = -1;
if (temp && strlen(temp) && (sscanf(temp, "%i", &result.handle) == 1) && (result.handle > -1)) {
if (!ast_osp_terminate(result.handle, cause, start, duration)) {
pbx_builtin_setvar_helper(chan, "OSPHANDLE", "");
res = 1;
}
} else {
if (!res) {
if (result.handle > -1)
ast_log(LOG_NOTICE, "OSP Finish failed for handle '%d'\n", result.handle);
else
ast_log(LOG_DEBUG, "No OSP handle specified\n");
} else
ast_log(LOG_DEBUG, "Got hangup on '%s' while doing OSP Terminate!\n", chan->name);
}
if (!res) {
/* Look for a "busy" place */
if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 101, chan->callerid))
chan->priority += 100;
} else if (res > 0)
res = 0;
LOCAL_USER_REMOVE(u);
return res;
}
int unload_module(void)
{
int res;
STANDARD_HANGUP_LOCALUSERS;
res = ast_unregister_application(app3);
res |= ast_unregister_application(app2);
res |= ast_unregister_application(app);
return res;
}
int load_module(void)
{
int res;
res = ast_register_application(app, osplookup_exec, synopsis, descrip);
if (res)
return(res);
res = ast_register_application(app2, ospnext_exec, synopsis2, descrip2);
if (res)
return(res);
res = ast_register_application(app3, ospfinished_exec, synopsis3, descrip3);
if (res)
return(res);
return(0);
}
int reload(void)
{
return 0;
}
char *description(void)
{
return tdesc;
}
int usecount(void)
{
int res;
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -1,253 +0,0 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* ParkAndAnnounce application for Asterisk
* Author: Ben Miller <bgmiller@dccinc.com>
* With TONS of help from Mark!
*
* Asterisk is Copyrighted as follows
* Copyright (C) 1999, Mark Spencer
*
* Mark Spencer <markster@linux-support.net>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*/
#include <sys/types.h>
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <asterisk/channel_pvt.h>
#include <asterisk/pbx.h>
#include <asterisk/module.h>
#include <asterisk/features.h>
#include <asterisk/options.h>
#include <asterisk/logger.h>
#include <asterisk/say.h>
#include <asterisk/lock.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
static char *tdesc = "Call Parking and Announce Application";
static char *app = "ParkAndAnnounce";
static char *synopsis = "Park and Announce";
static char *descrip =
" ParkAndAnnounce(announce:template|timeout|dial|[return_context]):\n"
"Park a call into the parkinglot and announce the call over the console.\n"
"announce template: colon separated list of files to announce, the word PARKED\n"
" will be replaced by a say_digits of the ext the call is parked in\n"
"timeout: time in seconds before the call returns into the return context.\n"
"dial: The app_dial style resource to call to make the announcement. Console/dsp calls the console.\n"
"return_context: the goto style label to jump the call back into after timeout. default=prio+1\n";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
static int parkandannounce_exec(struct ast_channel *chan, void *data)
{
int res=0;
char *return_context;
int l, lot, timeout = 0, dres;
char *working, *context, *exten, *priority, *dial, *dialtech, *dialstr;
char *template, *tpl_working, *tpl_current;
char *tmp[100];
int looptemp=0,i=0;
char *s,*orig_s;
struct ast_channel *dchan;
int outstate;
struct localuser *u;
if(!data || (data && !strlen(data))) {
ast_log(LOG_WARNING, "ParkAndAnnounce requires arguments: (announce:template|timeout|dial|[return_context])\n");
return -1;
}
l=strlen(data)+2;
orig_s=malloc(l);
if(!orig_s) {
ast_log(LOG_WARNING, "Out of memory\n");
return -1;
}
s=orig_s;
strncpy(s,data,l);
template=strsep(&s,"|");
if(! template) {
ast_log(LOG_WARNING, "PARK: An announce template must be defined\n");
free(orig_s);
return -1;
}
if(s) {
timeout = atoi(strsep(&s, "|"));
timeout *= 1000;
}
dial=strsep(&s, "|");
if(!dial) {
ast_log(LOG_WARNING, "PARK: A dial resource must be specified i.e: Console/dsp or Zap/g1/5551212\n");
free(orig_s);
return -1;
} else {
dialtech=strsep(&dial, "/");
dialstr=dial;
ast_verbose( VERBOSE_PREFIX_3 "Dial Tech,String: (%s,%s)\n", dialtech,dialstr);
}
return_context = s;
if(return_context != NULL) {
/* set the return context. Code borrowed from the Goto builtin */
working = return_context;
context = strsep(&working, "|");
exten = strsep(&working, "|");
if(!exten) {
/* Only a priority in this one */
priority = context;
exten = NULL;
context = NULL;
} else {
priority = strsep(&working, "|");
if(!priority) {
/* Only an extension and priority in this one */
priority = exten;
exten = context;
context = NULL;
}
}
if(atoi(priority) < 0) {
ast_log(LOG_WARNING, "Priority '%s' must be a number > 0\n", priority);
free(orig_s);
return -1;
}
/* At this point we have a priority and maybe an extension and a context */
chan->priority = atoi(priority);
if(exten && strcasecmp(exten, "BYEXTENSION"))
strncpy(chan->exten, exten, sizeof(chan->exten)-1);
if(context)
strncpy(chan->context, context, sizeof(chan->context)-1);
} else { /* increment the priority by default*/
chan->priority++;
}
if(option_verbose > 2) {
ast_verbose( VERBOSE_PREFIX_3 "Return Context: (%s,%s,%d) ID: %s\n", chan->context,chan->exten, chan->priority, chan->callerid);
if(!ast_exists_extension(chan, chan->context, chan->exten, chan->priority, chan->callerid)) {
ast_verbose( VERBOSE_PREFIX_3 "Warning: Return Context Invalid, call will return to default|s\n");
}
}
LOCAL_USER_ADD(u);
/* we are using masq_park here to protect * from touching the channel once we park it. If the channel comes out of timeout
before we are done announcing and the channel is messed with, Kablooeee. So we use Masq to prevent this. */
ast_masq_park_call(chan, NULL, timeout, &lot);
res=-1;
ast_verbose( VERBOSE_PREFIX_3 "Call Parking Called, lot: %d, timeout: %d, context: %s\n", lot, timeout, return_context);
/* Now place the call to the extention */
dchan = ast_request_and_dial(dialtech, AST_FORMAT_SLINEAR, dialstr,30000, &outstate, chan->callerid);
if(dchan) {
if(dchan->_state == AST_STATE_UP) {
if(option_verbose > 3)
ast_verbose(VERBOSE_PREFIX_4 "Channel %s was answered.\n", dchan->name);
} else {
if(option_verbose > 3)
ast_verbose(VERBOSE_PREFIX_4 "Channel %s was never answered.\n", dchan->name);
ast_log(LOG_WARNING, "PARK: Channel %s was never answered for the announce.\n", dchan->name);
ast_hangup(dchan);
free(orig_s);
LOCAL_USER_REMOVE(u);
return -1;
}
} else {
ast_log(LOG_WARNING, "PARK: Unable to allocate announce channel.\n");
free(orig_s);
LOCAL_USER_REMOVE(u);
return -1;
}
ast_stopstream(dchan);
/* now we have the call placed and are ready to play stuff to it */
ast_verbose(VERBOSE_PREFIX_4 "Announce Template:%s\n", template);
tpl_working = template;
tpl_current=strsep(&tpl_working, ":");
while(tpl_current && looptemp < sizeof(tmp)) {
tmp[looptemp]=tpl_current;
looptemp++;
tpl_current=strsep(&tpl_working,":");
}
for(i=0; i<looptemp; i++) {
ast_verbose(VERBOSE_PREFIX_4 "Announce:%s\n", tmp[i]);
if(!strcmp(tmp[i], "PARKED")) {
ast_say_digits(dchan, lot, "", dchan->language);
} else {
dres = ast_streamfile(dchan, tmp[i], dchan->language);
if(!dres) {
dres = ast_waitstream(dchan, "");
} else {
ast_log(LOG_WARNING, "ast_streamfile of %s failed on %s\n", tmp[i], dchan->name);
dres = 0;
}
}
}
ast_stopstream(dchan);
ast_hangup(dchan);
LOCAL_USER_REMOVE(u);
free(orig_s);
return res;
}
int unload_module(void)
{
STANDARD_HANGUP_LOCALUSERS;
return ast_unregister_application(app);
}
int load_module(void)
{
/* return ast_register_application(app, park_exec); */
return ast_register_application(app, parkandannounce_exec, synopsis, descrip);
}
char *description(void)
{
return tdesc;
}
int usecount(void)
{
int res;
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -11,34 +11,20 @@
* the GNU General Public License
*/
#include <asterisk/lock.h>
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <asterisk/pbx.h>
#include <asterisk/module.h>
#include <asterisk/translate.h>
#include <asterisk/utils.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
static char *tdesc = "Trivial Playback Application";
static char *app = "Playback";
static char *synopsis = "Play a file";
static char *descrip =
" Playback(filename[|option]): Plays back a given filename (do not put\n"
"extension). Options may also be included following a pipe symbol. The 'skip'\n"
"option causes the playback of the message to be skipped if the channel\n"
"is not in the 'up' state (i.e. it hasn't been answered yet. If 'skip' is \n"
"specified, the application will return immediately should the channel not be\n"
"off hook. Otherwise, unless 'noanswer' is specified, the channel channel will\n"
"be answered before the sound is played. Not all channels support playing\n"
"messages while still hook. Returns -1 if the channel was hung up, or if the\n"
"file does not exist. Returns 0 otherwise.\n";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
@@ -47,42 +33,20 @@ static int playback_exec(struct ast_channel *chan, void *data)
{
int res = 0;
struct localuser *u;
char tmp[256];
char *options;
int option_skip=0;
int option_noanswer = 0;
char *stringp;
if (!data || ast_strlen_zero((char *)data)) {
if (!data) {
ast_log(LOG_WARNING, "Playback requires an argument (filename)\n");
return -1;
}
strncpy(tmp, (char *)data, sizeof(tmp)-1);
stringp=tmp;
strsep(&stringp, "|");
options = strsep(&stringp, "|");
if (options && !strcasecmp(options, "skip"))
option_skip = 1;
if (options && !strcasecmp(options, "noanswer"))
option_noanswer = 1;
LOCAL_USER_ADD(u);
if (chan->_state != AST_STATE_UP) {
if (option_skip) {
/* At the user's option, skip if the line is not up */
LOCAL_USER_REMOVE(u);
return 0;
} else if (!option_noanswer)
/* Otherwise answer unless we're supposed to send this while on-hook */
res = ast_answer(chan);
}
if (chan->state != AST_STATE_UP)
res = ast_answer(chan);
if (!res) {
ast_stopstream(chan);
res = ast_streamfile(chan, tmp, chan->language);
res = ast_streamfile(chan, (char *)data, chan->language);
if (!res)
res = ast_waitstream(chan, "");
else {
else
ast_log(LOG_WARNING, "ast_streamfile failed on %s for %s\n", chan->name, (char *)data);
res = 0;
}
ast_stopstream(chan);
}
LOCAL_USER_REMOVE(u);
@@ -97,7 +61,7 @@ int unload_module(void)
int load_module(void)
{
return ast_register_application(app, playback_exec, synopsis, descrip);
return ast_register_application(app, playback_exec);
}
char *description(void)
@@ -111,8 +75,3 @@ int usecount(void)
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -1,170 +0,0 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* Block all calls without Caller*ID, require phone # to be entered
*
* Copyright (C) 1999, Mark Spencer
*
* Mark Spencer <markster@linux-support.net>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*/
#include <asterisk/lock.h>
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/options.h>
#include <asterisk/channel.h>
#include <asterisk/pbx.h>
#include <asterisk/module.h>
#include <asterisk/translate.h>
#include <asterisk/image.h>
#include <asterisk/callerid.h>
#include <asterisk/app.h>
#include <asterisk/config.h>
#include <string.h>
#include <stdlib.h>
#define PRIV_CONFIG "privacy.conf"
static char *tdesc = "Require phone number to be entered, if no CallerID sent";
static char *app = "PrivacyManager";
static char *synopsis = "Require phone number to be entered, if no CallerID sent";
static char *descrip =
" PrivacyManager: If no Caller*ID is sent, PrivacyManager answers the\n"
"channel and asks the caller to enter their 10 digit phone number.\n"
"The caller is given 3 attempts. If after 3 attempts, they do not enter\n"
"their 10 digit phone number, and if there exists a priority n + 101,\n"
"where 'n' is the priority of the current instance, then the\n"
"channel will be setup to continue at that priority level.\n"
"Otherwise, it returns 0. Does nothing if Caller*ID was received on the\n"
"channel.\n";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
static int
privacy_exec (struct ast_channel *chan, void *data)
{
int res=0;
int retries;
int maxretries = 3;
int x;
char *s;
char phone[10];
char new_cid[144];
struct localuser *u;
struct ast_config *cfg;
LOCAL_USER_ADD (u);
if (chan->callerid)
{
if (option_verbose > 2)
ast_verbose (VERBOSE_PREFIX_3 "CallerID Present: Skipping\n");
}
else
{
/*Answer the channel if it is not already*/
if (chan->_state != AST_STATE_UP) {
res = ast_answer(chan);
if (res) {
LOCAL_USER_REMOVE(u);
return -1;
}
}
/*Read in the config file*/
cfg = ast_load(PRIV_CONFIG);
/*Play unidentified call*/
res = ast_safe_sleep(chan, 1000);
if (!res)
res = ast_streamfile(chan, "privacy-unident", chan->language);
if (!res)
res = ast_waitstream(chan, "");
if (cfg && (s = ast_variable_retrieve(cfg, "general", "maxretries"))) {
if (sscanf(s, "%d", &x) == 1) {
maxretries = x;
} else {
ast_log(LOG_WARNING, "Invalid max retries argument\n");
}
}
/*Ask for 10 digit number, give 3 attempts*/
for (retries = 0; retries < maxretries; retries++) {
if (!res)
res = ast_app_getdata(chan, "privacy-prompt", phone, sizeof(phone), 0);
if (res < 0)
break;
/*Make sure we get 10 digits*/
if (strlen(phone) == 10)
break;
else {
res = ast_streamfile(chan, "privacy-incorrect", chan->language);
if (!res)
res = ast_waitstream(chan, "");
}
}
/*Got a number, play sounds and send them on their way*/
if ((retries < maxretries) && !res) {
res = ast_streamfile(chan, "privacy-thankyou", chan->language);
if (!res)
res = ast_waitstream(chan, "");
snprintf (new_cid, sizeof (new_cid), "\"%s\" <%s>", "Privacy Manager", phone);
ast_set_callerid (chan, new_cid, 0);
if (option_verbose > 2)
ast_verbose (VERBOSE_PREFIX_3 "Changed Caller*ID to %s\n",new_cid);
} else {
/*Send the call to n+101 priority, where n is the current priority*/
if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 101, chan->callerid))
chan->priority+=100;
}
if (cfg)
ast_destroy(cfg);
}
LOCAL_USER_REMOVE (u);
return 0;
}
int
unload_module (void)
{
STANDARD_HANGUP_LOCALUSERS;
return ast_unregister_application (app);
}
int
load_module (void)
{
return ast_register_application (app, privacy_exec, synopsis,
descrip);
}
char *
description (void)
{
return tdesc;
}
int
usecount (void)
{
int res;
STANDARD_USECOUNT (res);
return res;
}
char *
key ()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -1,394 +0,0 @@
/** @file app_qcall.c
*
* Asterisk -- A telephony toolkit for Linux.
*
* Call back a party and connect them to a running pbx thread
*
* Copyright (C) 1999, Mark Spencer
*
* Mark Spencer <markster@linux-support.net>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*
* Call a user from a file contained within a queue (/var/spool/asterisk/qcall)
*
* The queue is a directory containing files with the call request information
* as a single line of text as follows:
*
* Dialstring Caller-ID Extension Maxsecs [Identifier] [Required-response]
*
* Dialstring -- A Dial String (The number to be called) in the
* format Technology/Number, such IAX/mysys/1234 or Zap/g1/1234
*
* Caller-ID -- A Standard nomalized representation of the Caller-ID of
* the number being dialed (generally 10 digits in the US). Leave as
* "asreceived" to use the default Caller*ID
*
* Extension -- The Extension (optionally Extension@context) that the
* user should be "transferred" to after acceptance of the call.
*
* Maxsecs -- The Maximum time of the call in seconds. Specify 0 for infinite.
*
* Identifier -- The "Identifier" of the request. This is used to determine
* the names of the audio prompt files played. The first prompt, the one that
* asks for the input, is just the exact string specified as the identifier.
* The second prompt, the one that is played after the correct input is given,
* (generally a "thank you" recording), is the specified string with "-ok"
* added to the end. So, if you specify "foo" as the identifier, your first
* prompt file that will be played will be "foo" and the second one will be
* "foo-ok". If omitted no prompt is given
*
* Required-Response (Optional) -- Specify a digit string to be used as the
* acceptance "code" if you desire it to be something other then "1". This
* can be used to implement some sort of PIN or security system. It may be
* more then a single character.
*
* NOTE: It is important to remember that the process that creates these
* files needs keep and maintain a write lock (using flock with the LOCK_EX
* option) when writing these files.
*
*/
#include <asterisk/lock.h>
#include <asterisk/utils.h>
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <asterisk/pbx.h>
#include <asterisk/module.h>
#include <asterisk/translate.h>
#include <asterisk/options.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <dirent.h>
#include <ctype.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/file.h>
#include "../astconf.h"
static char qdir[255];
static char *tdesc = "Call from Queue";
static pthread_t qcall_thread;
static int debug = 0;
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
#define OLDESTOK 14400 /* not any more then this number of secs old */
#define INITIALONE 1 /* initial wait before the first one in secs */
#define NEXTONE 600 /* wait before trying it again in secs */
#define MAXWAITFORANSWER 45000 /* max call time before answer */
/* define either one or both of these two if your application requires it */
#if 0
#define ACCTCODE "SOMETHING" /* Account code */
#define AMAFLAGS AST_CDR_BILLING /* AMA flags */
#endif
/* define this if you want to have a particular CLID display on the user's
phone when they receive the call */
#if 0
#define OURCLID "2564286275" /* The callerid to be displayed when calling */
#endif
static void *qcall_do(void *arg);
static void *qcall(void *ignore)
{
pthread_t dialer_thread;
DIR *dirp;
FILE *fp;
struct dirent *dp;
char fname[80];
struct stat mystat;
time_t t;
void *arg;
pthread_attr_t attr;
time(&t);
if (debug) printf("@@@@ qcall starting at %s",ctime(&t));
for(;;)
{
time(&t);
dirp = opendir(qdir);
if (!dirp)
{
perror("app_qcall:Cannot open queue directory");
break;
}
while((dp = readdir(dirp)) != NULL)
{
if (dp->d_name[0] == '.') continue;
snprintf(fname, sizeof(fname), "%s/%s", qdir, dp->d_name);
if (stat(fname,&mystat) == -1)
{
perror("app_qcall:stat");
fprintf(stderr,"%s\n",fname);
continue;
}
/* if not a regular file, skip it */
if ((mystat.st_mode & S_IFMT) != S_IFREG) continue;
/* if not yet .... */
if (mystat.st_atime == mystat.st_mtime)
{ /* first time */
if ((mystat.st_atime + INITIALONE) > t)
continue;
}
else
{ /* already looked at once */
if ((mystat.st_atime + NEXTONE) > t) continue;
}
/* if too old */
if (mystat.st_mtime < (t - OLDESTOK))
{
/* kill it, its too old */
unlink(fname);
continue;
}
/* "touch" file's access time */
fp = fopen(fname,"r");
if (fp) fclose(fp);
/* make a copy of the filename string, so that we
may go on and use the buffer */
arg = (void *) strdup(fname);
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
if (ast_pthread_create(&dialer_thread,&attr,qcall_do,arg) == -1)
{
perror("qcall: Cannot create thread");
continue;
}
}
closedir(dirp);
sleep(1);
}
pthread_exit(NULL);
}
/* single thread with one file (request) to dial */
static void *qcall_do(void *arg)
{
char fname[300] = "";
char dialstr[300];
char extstr[300];
char ident[300] = "";
char reqinp[300] = "";
char buf[300];
char clid[300],*tele,*context;
FILE *fp;
int ms = MAXWAITFORANSWER,maxsecs;
struct ast_channel *channel;
time_t t;
/* get the filename from the arg */
strncpy(fname,(char *)arg, sizeof(fname) - 1);
free(arg);
time(&t);
fp = fopen(fname,"r");
if (!fp) /* if cannot open request file */
{
perror("qcall_do:fopen");
fprintf(stderr,"%s\n",fname);
unlink(fname);
pthread_exit(NULL);
}
/* lock the file */
if (flock(fileno(fp),LOCK_EX) == -1)
{
perror("qcall_do:flock");
fprintf(stderr,"%s\n",fname);
pthread_exit(NULL);
}
/* default required input for acknowledgement */
reqinp[0] = '1';
reqinp[1] = '\0';
/* default no ident */
ident[0] = '\0'; /* default no ident */
if (fscanf(fp,"%s %s %s %d %s %s",dialstr,clid,
extstr,&maxsecs,ident,reqinp) < 4)
{
fprintf(stderr,"qcall_do:file line invalid in file %s:\n",fname);
pthread_exit(NULL);
}
flock(fileno(fp),LOCK_UN);
fclose(fp);
tele = strchr(dialstr,'/');
if (!tele)
{
fprintf(stderr,"qcall_do:Dial number must be in format tech/number\n");
unlink(fname);
pthread_exit(NULL);
}
*tele++ = 0;
channel = ast_request(dialstr,AST_FORMAT_SLINEAR,tele);
if (channel)
{
ast_set_read_format(channel,AST_FORMAT_SLINEAR);
ast_set_write_format(channel,AST_FORMAT_SLINEAR);
#ifdef OURCLID
if (channel->callerid)
free(channel->callerid);
channel->callerid = strdup(OURCLID);
if (channel->ani)
free(channel->ani);
channel->ani = strdup(OURCLID);
#endif
channel->whentohangup = 0;
channel->appl = "AppQcall";
channel->data = "(Outgoing Line)";
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "Qcall initiating call to %s/%s on %s (%s)\n",
dialstr,tele,channel->name,fname);
ast_call(channel,tele,MAXWAITFORANSWER);
}
else
{
fprintf(stderr,"qcall_do:Sorry unable to obtain channel\n");
pthread_exit(NULL);
}
if (strcasecmp(clid, "asreceived")) {
if (channel->callerid) free(channel->callerid);
channel->callerid = NULL;
if (channel->ani) free(channel->ani);
channel->ani = NULL;
}
if (channel->_state == AST_STATE_UP)
if (debug) printf("@@@@ Autodial:Line is Up\n");
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "Qcall waiting for answer on %s\n",
channel->name);
while(ms > 0){
struct ast_frame *f;
ms = ast_waitfor(channel,ms);
f = ast_read(channel);
if (!f)
{
if (debug) printf("@@@@ qcall_do:Hung Up\n");
unlink(fname);
break;
}
if (f->frametype == AST_FRAME_CONTROL)
{
if (f->subclass == AST_CONTROL_HANGUP)
{
if (debug) printf("@@@@ qcall_do:Hung Up\n");
unlink(fname);
ast_frfree(f);
break;
}
if (f->subclass == AST_CONTROL_ANSWER)
{
if (debug) printf("@@@@ qcall_do:Phone Answered\n");
if (channel->_state == AST_STATE_UP)
{
unlink(fname);
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "Qcall got answer on %s\n",
channel->name);
usleep(1500000);
if (strlen(ident)) {
ast_streamfile(channel,ident,0);
if (ast_readstring(channel,buf,strlen(reqinp),10000,5000,"#"))
{
ast_stopstream(channel);
if (debug) printf("@@@@ qcall_do: timeout or hangup in dtmf read\n");
ast_frfree(f);
break;
}
ast_stopstream(channel);
if (strcmp(buf,reqinp)) /* if not match */
{
if (debug) printf("@@@@ qcall_do: response (%s) does not match required (%s)\n",buf,reqinp);
ast_frfree(f);
break;
}
ast_frfree(f);
}
/* okay, now we go for it */
context = strchr(extstr,'@');
if (!context) context = "default";
else *context++ = 0;
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "Qcall got accept, now putting through to %s@%s on %s\n",
extstr,context,channel->name);
if (strlen(ident)) {
strncat(ident,"-ok", sizeof(ident) - strlen(ident) - 1);
/* if file existant, play it */
if (!ast_streamfile(channel,ident,0))
{
ast_waitstream(channel,"");
ast_stopstream(channel);
}
}
if (strcasecmp(clid, "asreceived")) {
channel->callerid = strdup(clid);
channel->ani = strdup(clid);
}
channel->language[0] = 0;
channel->dnid = strdup(extstr);
#ifdef AMAFLAGS
channel->amaflags = AMAFLAGS;
#endif
#ifdef ACCTCODE
strncpy(channel->accountcode, ACCTCODE, sizeof(chan->accountcode) - 1);
#else
channel->accountcode[0] = 0;
#endif
if (maxsecs) /* if finite length call */
{
time(&channel->whentohangup);
channel->whentohangup += maxsecs;
}
strncpy(channel->exten, extstr, sizeof(channel->exten) - 1);
strncpy(channel->context, context, sizeof(channel->context) - 1);
channel->priority = 1;
if(debug) printf("Caller ID is %s\n", channel->callerid);
ast_pbx_run(channel);
pthread_exit(NULL);
}
}
else if(f->subclass==AST_CONTROL_RINGING)
if (debug) printf("@@@@ qcall_do:Phone Ringing end\n");
}
ast_frfree(f);
}
ast_hangup(channel);
if (debug) printf("@@@@ qcall_do:Hung up channel\n");
pthread_exit(NULL);
return NULL;
}
int unload_module(void)
{
STANDARD_HANGUP_LOCALUSERS;
return 0;
}
int load_module(void)
{
snprintf(qdir, sizeof(qdir), "%s/%s", ast_config_AST_SPOOL_DIR, "qcall");
mkdir(qdir,0760);
ast_pthread_create(&qcall_thread,NULL,qcall,NULL);
return 0;
}
char *description(void)
{
return tdesc;
}
int usecount(void)
{
int res;
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,128 +0,0 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* Random application
*
* Copyright (c) 2003-2004 Tilghman Lesher. All rights reserved.
*
* Tilghman Lesher <asterisk__app_random__20040111@the-tilghman.com>
*
* This code is released by the author with no restrictions on usage or distribution.
*
*/
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/options.h>
#include <asterisk/channel.h>
#include <asterisk/pbx.h>
#include <asterisk/module.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
static char *tdesc = "Random goto";
static char *app_random = "Random";
static char *random_synopsis = "Conditionally branches, based upon a probability";
static char *random_descrip =
"Random([probability]:[[context|]extension|]priority)\n"
" probability := INTEGER in the range 1 to 100\n";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
static int random_exec(struct ast_channel *chan, void *data)
{
int res=0;
struct localuser *u;
char *s;
char *exten, *pri, *context;
char *prob;
int probint, priorityint;
if (!data) {
ast_log(LOG_WARNING, "Random requires an argument ([probability]:[[context|]extension|]priority)\n");
return -1;
}
LOCAL_USER_ADD(u);
s = ast_strdupa((void *) data);
prob = strsep(&s,":");
if ((!prob) || (sscanf(prob, "%d", &probint) != 1))
probint = 0;
if ((random() % 100) + probint > 100) {
context = strsep(&s, "|");
exten = strsep(&s, "|");
if (!exten) {
/* Only a priority */
pri = context;
exten = NULL;
context = NULL;
} else {
pri = strsep(&s, "|");
if (!pri) {
pri = exten;
exten = context;
context = NULL;
}
}
if (!pri) {
ast_log(LOG_WARNING, "No label specified\n");
LOCAL_USER_REMOVE(u);
return -1;
} else if (sscanf(pri, "%d", &priorityint) != 1) {
ast_log(LOG_WARNING, "Priority '%s' must be a number > 0\n", pri);
LOCAL_USER_REMOVE(u);
return -1;
}
/* At this point we have a priority and */
/* maybe an extension and a context */
chan->priority = priorityint - 1;
if (exten && strcasecmp(exten, "BYEXTENSION"))
strncpy(chan->exten, exten, sizeof(chan->exten)-1);
if (context)
strncpy(chan->context, context, sizeof(chan->context)-1);
if (option_verbose > 2)
ast_verbose( VERBOSE_PREFIX_3 "Random branches to (%s,%s,%d)\n",
chan->context,chan->exten, chan->priority+1);
LOCAL_USER_REMOVE(u);
}
return res;
}
int unload_module(void)
{
STANDARD_HANGUP_LOCALUSERS;
return ast_unregister_application(app_random);
}
int load_module(void)
{
srandom((unsigned int)getpid() + (unsigned int)time(NULL));
return ast_register_application(app_random, random_exec, random_synopsis, random_descrip);
}
char *description(void)
{
return tdesc;
}
int usecount(void)
{
int res;
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -1,144 +0,0 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* Trivial application to read a variable
*
* Copyright (C) 2003, Digium
*
* Mark Spencer <markster@digium.com>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*/
#include <asterisk/lock.h>
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <asterisk/pbx.h>
#include <asterisk/app.h>
#include <asterisk/module.h>
#include <asterisk/translate.h>
#include <asterisk/options.h>
#include <asterisk/utils.h>
#include <string.h>
#include <stdlib.h>
static char *tdesc = "Read Variable Application";
static char *app = "Read";
static char *synopsis = "Read a variable";
static char *descrip =
" Read(variable[|filename][|maxdigits][|option])\n\n"
"Reads a #-terminated string of digits from the user in to the given variable,\n"
"optionally playing a given filename first.\n"
" maxdigits -- maximum acceptable number of digits. Stops reading after\n"
" maxdigits have been entered (without requiring the user to\n"
" press the '#' key).\n"
" Defaults to 0 - no limit - wait for the user press the '#' key.\n"
" Any value below 0 means the same. Max accepted value is 255.\n"
" option -- may be 'skip' to return immediately if the line is not up,\n"
" or 'noanswer' to read digits even if the line is not up.\n\n"
"Returns -1 on hangup or error and 0 otherwise.\n";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
static int read_exec(struct ast_channel *chan, void *data)
{
int res = 0;
struct localuser *u;
char tmp[256];
char argdata[256] = "";
char *varname;
char *filename;
char *stringp;
char *maxdigitstr;
char *options;
int option_skip = 0;
int option_noanswer = 0;
int maxdigits=255;
if (!data || ast_strlen_zero((char *)data)) {
ast_log(LOG_WARNING, "Read requires an argument (variable)\n");
return -1;
}
strncpy(argdata, (char *)data, sizeof(argdata)-1);
stringp=argdata;
varname = strsep(&stringp, "|");
filename = strsep(&stringp, "|");
maxdigitstr = strsep(&stringp,"|");
options = strsep(&stringp, "|");
if (options && !strcasecmp(options, "skip"))
option_skip = 1;
if (options && !strcasecmp(options, "noanswer"))
option_noanswer = 1;
if (!(filename) || ast_strlen_zero(filename))
filename = NULL;
if (maxdigitstr) {
maxdigits = atoi(maxdigitstr);
if ((maxdigits<1) || (maxdigits>255)) {
maxdigits = 255;
} else
ast_verbose(VERBOSE_PREFIX_3 "Accepting a maximum of %i digits.\n", maxdigits);
}
if (!(varname) || ast_strlen_zero(varname)) {
ast_log(LOG_WARNING, "Read requires an variable name\n");
return -1;
}
LOCAL_USER_ADD(u);
if (chan->_state != AST_STATE_UP) {
if (option_skip) {
/* At the user's option, skip if the line is not up */
pbx_builtin_setvar_helper(chan, varname, "\0");
LOCAL_USER_REMOVE(u);
return 0;
} else if (!option_noanswer) {
/* Otherwise answer unless we're supposed to read while on-hook */
res = ast_answer(chan);
}
}
if (!res) {
ast_stopstream(chan);
res = ast_app_getdata(chan, filename, tmp, maxdigits, 0);
if (res > -1) {
pbx_builtin_setvar_helper(chan, varname, tmp);
ast_verbose(VERBOSE_PREFIX_3 "User entered '%s'\n", tmp);
res = 0;
} else {
ast_verbose(VERBOSE_PREFIX_3 "User disconnected\n");
}
}
LOCAL_USER_REMOVE(u);
return res;
}
int unload_module(void)
{
STANDARD_HANGUP_LOCALUSERS;
return ast_unregister_application(app);
}
int load_module(void)
{
return ast_register_application(app, read_exec, synopsis, descrip);
}
char *description(void)
{
return tdesc;
}
int usecount(void)
{
int res;
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -1,340 +0,0 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* Trivial application to record a sound file
*
* Copyright (C) 2001, Linux Support Services, Inc.
*
* Matthew Fredrickson <creslin@linux-support.net>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*/
#include <asterisk/lock.h>
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <asterisk/pbx.h>
#include <asterisk/module.h>
#include <asterisk/translate.h>
#include <asterisk/dsp.h>
#include <string.h>
#include <stdlib.h>
static char *tdesc = "Trivial Record Application";
static char *app = "Record";
static char *synopsis = "Record to a file";
static char *descrip =
" Record(filename:format|silence[|maxduration][|option])\n\n"
"Records from the channel into a given filename. If the file exists it will\n"
"be overwritten.\n"
"- 'format' is the format of the file type to be recorded (wav, gsm, etc).\n"
"- 'silence' is the number of seconds of silence to allow before returning.\n"
"- 'maxduration' is the maximum recording duration in seconds. If missing\n"
"or 0 there is no maximum.\n"
"- 'option' may be 'skip' to return immediately if the line is not up,\n"
"or 'noanswer' to attempt to record even if the line is not up.\n\n"
"If filename contains '%d', these characters will be replaced with a number\n"
"incremented by one each time the file is recorded. \n\n"
"Formats: g723, g729, gsm, h263, ulaw, alaw, vox, wav, WAV\n\n"
"User can press '#' to terminate the recording and continue to the next priority.\n\n"
"Returns -1 when the user hangs up.\n";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
static int record_exec(struct ast_channel *chan, void *data)
{
int res = 0;
int count = 0;
int percentflag = 0;
char fil[256];
char tmp[256];
char ext[10];
char *vdata;
int i = 0;
int j = 0;
struct ast_filestream *s = '\0';
struct localuser *u;
struct ast_frame *f = NULL;
struct ast_dsp *sildet = NULL; /* silence detector dsp */
int totalsilence = 0;
int dspsilence = 0;
int silence = 0; /* amount of silence to allow */
int gotsilence = 0; /* did we timeout for silence? */
char silencestr[5];
char durationstr[8];
int maxduration = 0; /* max duration of recording */
int gottimeout = 0; /* did we timeout for maxduration exceeded? */
time_t timeout = 0;
char option[16];
int option_skip = 0;
int option_noanswer = 0;
int rfmt = 0;
int flags;
char *end=NULL;
char *p=NULL;
/* The next few lines of code parse out the filename and header from the input string */
if (!data) { /* no data implies no filename or anything is present */
ast_log(LOG_WARNING, "Record requires an argument (filename)\n");
return -1;
}
vdata = ast_strdupa(data);
p = vdata;
while(p && (p=strchr(p,':'))) {
end=p;
if(!strcasecmp(end,":end")) {
*end='\0';
end++;
break;
}
p++;
end=NULL;
}
for (; vdata[i] && (vdata[i] != ':') && (vdata[i] != '|'); i++ ) {
if ((vdata[i] == '%') && (vdata[i+1] == 'd')) {
percentflag = 1; /* the wildcard is used */
}
if (j < sizeof(fil) - 1)
fil[j++] = vdata[i];
}
fil[j] = '\0';
if (vdata[i] != ':') {
ast_log(LOG_WARNING, "No extension found\n");
return -1;
}
i++;
j = 0;
for (; vdata[i] && (vdata[i] != '|'); i++)
if (j < sizeof(ext) - 1)
ext[j++] = vdata[i];
ext[j] = '\0';
if (vdata[i] == '|')
i++;
j = 0;
for (; vdata[i] && (vdata[i] != '|'); i++)
if (j < sizeof(silencestr) - 1)
silencestr[j++] = vdata[i];
silencestr[j] = '\0';
if (j > 0) {
silence = atoi(silencestr);
if (silence > 0)
silence *= 1000;
}
if (vdata[i] == '|')
i++;
j = 0;
for (; vdata[i] && (vdata[i] != '|'); i++)
if (j < sizeof(durationstr) - 1)
durationstr[j++] = vdata[i];
durationstr[j] = '\0';
if (j > 0)
maxduration = atoi(durationstr);
if (vdata[i] == '|')
i++;
j = 0;
for (; vdata[i] && (vdata[i] != '|'); i++)
if (j < sizeof(option) - 1)
option[j++] = vdata[i];
option[j] = '\0';
if (!strcasecmp(option, "skip"))
option_skip = 1;
if (!strcasecmp(option, "noanswer"))
option_noanswer = 1;
/* done parsing */
/* these are to allow the use of the %d in the config file for a wild card of sort to
create a new file with the inputed name scheme */
if (percentflag) {
do {
snprintf(tmp, sizeof(tmp), fil, count);
count++;
} while ( ast_fileexists(tmp, ext, chan->language) != -1 );
pbx_builtin_setvar_helper(chan, "RECORDED_FILE", tmp);
} else
strncpy(tmp, fil, sizeof(tmp)-1);
/* end of routine mentioned */
LOCAL_USER_ADD(u);
if (chan->_state != AST_STATE_UP) {
if (option_skip) {
/* At the user's option, skip if the line is not up */
LOCAL_USER_REMOVE(u);
return 0;
} else if (!option_noanswer) {
/* Otherwise answer unless we're supposed to record while on-hook */
res = ast_answer(chan);
}
}
if (!res) {
/* Some code to play a nice little beep to signify the start of the record operation */
res = ast_streamfile(chan, "beep", chan->language);
if (!res) {
res = ast_waitstream(chan, "");
} else {
ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", chan->name);
}
ast_stopstream(chan);
/* The end of beep code. Now the recording starts */
if (silence > 0) {
rfmt = chan->readformat;
res = ast_set_read_format(chan, AST_FORMAT_SLINEAR);
if (res < 0) {
ast_log(LOG_WARNING, "Unable to set to linear mode, giving up\n");
return -1;
}
sildet = ast_dsp_new();
if (!sildet) {
ast_log(LOG_WARNING, "Unable to create silence detector :(\n");
return -1;
}
ast_dsp_set_threshold(sildet, 256);
}
flags = end ? O_CREAT|O_APPEND|O_WRONLY : O_CREAT|O_TRUNC|O_WRONLY;
s = ast_writefile( tmp, ext, NULL, flags , 0, 0644);
if (s) {
if (maxduration > 0)
timeout = time(NULL) + (time_t)maxduration;
while (ast_waitfor(chan, -1) > -1) {
if (maxduration > 0 && time(NULL) > timeout) {
gottimeout = 1;
break;
}
f = ast_read(chan);
if (!f) {
res = -1;
break;
}
if (f->frametype == AST_FRAME_VOICE) {
res = ast_writestream(s, f);
if (res) {
ast_log(LOG_WARNING, "Problem writing frame\n");
break;
}
if (silence > 0) {
dspsilence = 0;
ast_dsp_silence(sildet, f, &dspsilence);
if (dspsilence) {
totalsilence = dspsilence;
} else {
totalsilence = 0;
}
if (totalsilence > silence) {
/* Ended happily with silence */
ast_frfree(f);
gotsilence = 1;
break;
}
}
}
if (f->frametype == AST_FRAME_VIDEO) {
res = ast_writestream(s, f);
if (res) {
ast_log(LOG_WARNING, "Problem writing frame\n");
break;
}
}
if ((f->frametype == AST_FRAME_DTMF) &&
(f->subclass == '#')) {
ast_frfree(f);
break;
}
ast_frfree(f);
}
if (!f) {
ast_log(LOG_DEBUG, "Got hangup\n");
res = -1;
}
if (gotsilence) {
ast_stream_rewind(s, silence-1000);
ast_truncstream(s);
} else if (!gottimeout) {
/* Strip off the last 1/4 second of it */
ast_stream_rewind(s, 250);
ast_truncstream(s);
}
ast_closestream(s);
} else
ast_log(LOG_WARNING, "Could not create file %s\n", fil);
} else
ast_log(LOG_WARNING, "Could not answer channel '%s'\n", chan->name);
LOCAL_USER_REMOVE(u);
if ((silence > 0) && rfmt) {
res = ast_set_read_format(chan, rfmt);
if (res)
ast_log(LOG_WARNING, "Unable to restore read format on '%s'\n", chan->name);
if (sildet)
ast_dsp_free(sildet);
}
return res;
}
int unload_module(void)
{
STANDARD_HANGUP_LOCALUSERS;
return ast_unregister_application(app);
}
int load_module(void)
{
return ast_register_application(app, record_exec, synopsis, descrip);
}
char *description(void)
{
return tdesc;
}
int usecount(void)
{
int res;
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,141 +0,0 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* SayUnixTime application
*
* Copyright (c) 2003 Tilghman Lesher. All rights reserved.
*
* Tilghman Lesher <app_sayunixtime__200309@the-tilghman.com>
*
* This code is released by the author with no restrictions on usage.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/options.h>
#include <asterisk/channel.h>
#include <asterisk/pbx.h>
#include <asterisk/module.h>
#include <asterisk/say.h>
static char *tdesc = "Say time";
static char *app_sayunixtime = "SayUnixTime";
static char *app_datetime = "DateTime";
static char *sayunixtime_synopsis = "Says a specified time in a custom format";
static char *sayunixtime_descrip =
"SayUnixTime([unixtime][|[timezone][|format]])\n"
" unixtime: time, in seconds since Jan 1, 1970. May be negative.\n"
" defaults to now.\n"
" timezone: timezone, see /usr/share/zoneinfo for a list.\n"
" defaults to machine default.\n"
" format: a format the time is to be said in. See voicemail.conf.\n"
" defaults to \"ABdY 'digits/at' IMp\"\n"
" Returns 0 or -1 on hangup.\n";
static char *datetime_descrip =
"DateTime([unixtime][|[timezone][|format]])\n"
" unixtime: time, in seconds since Jan 1, 1970. May be negative.\n"
" defaults to now.\n"
" timezone: timezone, see /usr/share/zoneinfo for a list.\n"
" defaults to machine default.\n"
" format: a format the time is to be said in. See voicemail.conf.\n"
" defaults to \"ABdY 'digits/at' IMp\"\n"
" Returns 0 or -1 on hangup.\n";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
static int sayunixtime_exec(struct ast_channel *chan, void *data)
{
int res=0;
struct localuser *u;
char *s,*zone=NULL,*timec;
time_t unixtime;
char *format = "ABdY 'digits/at' IMp";
struct timeval tv;
LOCAL_USER_ADD(u);
gettimeofday(&tv,NULL);
unixtime = (time_t)tv.tv_sec;
if (data) {
s = data;
s = ast_strdupa(s);
if (s) {
timec = strsep(&s,"|");
if ((timec) && (*timec != '\0')) {
long timein;
if (sscanf(timec,"%ld",&timein) == 1) {
unixtime = (time_t)timein;
}
}
if (s) {
zone = strsep(&s,"|");
if (zone && (*zone == '\0'))
zone = NULL;
if (s) {
format = s;
}
}
} else {
ast_log(LOG_ERROR, "Out of memory error\n");
}
}
if (chan->_state != AST_STATE_UP) {
res = ast_answer(chan);
}
if (!res)
res = ast_say_date_with_format(chan, unixtime, AST_DIGIT_ANY, chan->language, format, zone);
LOCAL_USER_REMOVE(u);
return res;
}
int unload_module(void)
{
int res;
STANDARD_HANGUP_LOCALUSERS;
res = ast_unregister_application(app_sayunixtime);
if (! res)
return ast_unregister_application(app_datetime);
else
return res;
}
int load_module(void)
{
int res;
res = ast_register_application(app_sayunixtime, sayunixtime_exec, sayunixtime_synopsis, sayunixtime_descrip);
if (! res)
return ast_register_application(app_datetime, sayunixtime_exec, sayunixtime_synopsis, datetime_descrip);
else
return res;
}
char *description(void)
{
return tdesc;
}
int usecount(void)
{
int res;
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -1,84 +0,0 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* App to send DTMF digits
*
* Copyright (C) 1999, Mark Spencer
*
* Mark Spencer <markster@linux-support.net>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*/
#include <asterisk/lock.h>
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <asterisk/pbx.h>
#include <asterisk/module.h>
#include <asterisk/translate.h>
#include <asterisk/options.h>
#include <asterisk/utils.h>
#include <asterisk/app.h>
#include <string.h>
#include <stdlib.h>
static char *tdesc = "Send DTMF digits Application";
static char *app = "SendDTMF";
static char *synopsis = "Sends arbitrary DTMF digits";
static char *descrip =
" SendDTMF(digits): Sends DTMF digits on a channel. \n"
" Accepted digits: 0-9, *#abcd\n"
" Returns 0 on success or -1 on a hangup.\n";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
static int senddtmf_exec(struct ast_channel *chan, void *data)
{
int res = 0;
struct localuser *u;
char *digits = data;
if (!digits || ast_strlen_zero(digits)) {
ast_log(LOG_WARNING, "SendDTMF requires an argument (digits or *#aAbBcCdD)\n");
return -1;
}
LOCAL_USER_ADD(u);
res = ast_dtmf_stream(chan,NULL,digits,250);
LOCAL_USER_REMOVE(u);
return res;
}
int unload_module(void)
{
STANDARD_HANGUP_LOCALUSERS;
return ast_unregister_application(app);
}
int load_module(void)
{
return ast_register_application(app, senddtmf_exec, synopsis, descrip);
}
char *description(void)
{
return tdesc;
}
int usecount(void)
{
int res;
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -1,94 +0,0 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* App to transmit a text message
*
* Copyright (C) 1999, Mark Spencer
*
* Mark Spencer <markster@linux-support.net>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*/
#include <asterisk/lock.h>
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <asterisk/channel_pvt.h>
#include <asterisk/pbx.h>
#include <asterisk/module.h>
#include <asterisk/translate.h>
#include <asterisk/image.h>
#include <string.h>
#include <stdlib.h>
static char *tdesc = "Send Text Applications";
static char *app = "SendText";
static char *synopsis = "Send a Text Message";
static char *descrip =
" SendText(text): Sends text to client. If the client\n"
"does not support text transport, and there exists a step with\n"
"priority n + 101, then execution will continue at that step.\n"
"Otherwise, execution will continue at the next priority level.\n"
"SendText only returns 0 if the text was sent correctly or if\n"
"the channel does not support text transport, and -1 otherwise.\n";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
static int sendtext_exec(struct ast_channel *chan, void *data)
{
int res = 0;
struct localuser *u;
if (!data || !strlen((char *)data)) {
ast_log(LOG_WARNING, "SendText requires an argument (text)\n");
return -1;
}
LOCAL_USER_ADD(u);
ast_mutex_lock(&chan->lock);
if (!chan->pvt->send_text) {
ast_mutex_unlock(&chan->lock);
/* Does not support transport */
if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 101, chan->callerid))
chan->priority += 100;
LOCAL_USER_REMOVE(u);
return 0;
}
ast_mutex_unlock(&chan->lock);
res = ast_sendtext(chan, (char *)data);
LOCAL_USER_REMOVE(u);
return res;
}
int unload_module(void)
{
STANDARD_HANGUP_LOCALUSERS;
return ast_unregister_application(app);
}
int load_module(void)
{
return ast_register_application(app, sendtext_exec, synopsis, descrip);
}
char *description(void)
{
return tdesc;
}
int usecount(void)
{
int res;
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -1,159 +0,0 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* App to set callerid
*
* Copyright (C) 1999, Mark Spencer
*
* Mark Spencer <markster@linux-support.net>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*/
#include <asterisk/lock.h>
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <asterisk/pbx.h>
#include <asterisk/module.h>
#include <asterisk/translate.h>
#include <asterisk/image.h>
#include <asterisk/callerid.h>
#include <string.h>
#include <stdlib.h>
static char *app2 = "SetCallerPres";
static char *synopsis2 = "Set CallerID Presentation";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
static struct {
int val;
char *name;
} preses[] = {
{ AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, "allowed_not_screened" },
{ AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, "allowed_passed_screen" },
{ AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN, "allowed_failed_screen" },
{ AST_PRES_ALLOWED_NETWORK_NUMBER, "allowed" },
{ AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED , "prohib_not_screened" },
{ AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN, "prohib_passed_screen" },
{ AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN, "prohib_failed_screen" },
{ AST_PRES_PROHIB_NETWORK_NUMBER, "prohib" },
{ AST_PRES_NUMBER_NOT_AVAILABLE, "unavailable" },
};
static char *descrip2 =
" SetCallerPres(presentation): Set Caller*ID presentation on\n"
"a call to a new value. Sets ANI as well if a flag is used.\n"
"Always returns 0. Valid presentations are:\n"
"\n"
" allowed_not_screened : Presentation Allowed, Not Screened\n"
" allowed_passed_screen : Presentation Allowed, Passed Screen\n"
" allowed_failed_screen : Presentation Allowed, Failed Screen\n"
" allowed : Presentation Allowed, Network Number\n"
" prohib_not_screened : Presentation Prohibited, Not Screened\n"
" prohib_passed_screen : Presentation Prohibited, Passed Screen\n"
" prohib_failed_screen : Presentation Prohibited, Failed Screen\n"
" prohib : Presentation Prohibited, Network Number\n"
" unavailable : Number Unavailable\n"
"\n"
;
static int setcallerid_pres_exec(struct ast_channel *chan, void *data)
{
int res = 0;
char tmp[256] = "";
struct localuser *u;
int x;
char *opts;
int pres = -1;
if (data)
strncpy(tmp, (char *)data, sizeof(tmp) - 1);
opts = strchr(tmp, '|');
if (opts) {
*opts = '\0';
opts++;
}
for (x=0;x<sizeof(preses) / sizeof(preses[0]);x++) {
if (!strcasecmp(preses[x].name, tmp)) {
pres = preses[x].val;
break;
}
}
if (pres < 0) {
ast_log(LOG_WARNING, "'%s' is not a valid presentation (see 'show application SetCallerPres')\n", tmp);
return 0;
}
LOCAL_USER_ADD(u);
chan->callingpres = pres;
LOCAL_USER_REMOVE(u);
return res;
}
static char *tdesc = "Set CallerID Application";
static char *app = "SetCallerID";
static char *synopsis = "Set CallerID";
static char *descrip =
" SetCallerID(clid[|a]): Set Caller*ID on a call to a new\n"
"value. Sets ANI as well if a flag is used. Always returns 0\n";
static int setcallerid_exec(struct ast_channel *chan, void *data)
{
int res = 0;
char tmp[256] = "";
struct localuser *u;
char *opt;
int anitoo = 0;
if (data)
strncpy(tmp, (char *)data, sizeof(tmp) - 1);
opt = strchr(tmp, '|');
if (opt) {
*opt = '\0';
opt++;
if (*opt == 'a')
anitoo = 1;
}
LOCAL_USER_ADD(u);
ast_set_callerid(chan, strlen(tmp) ? tmp : NULL, anitoo);
LOCAL_USER_REMOVE(u);
return res;
}
int unload_module(void)
{
STANDARD_HANGUP_LOCALUSERS;
ast_unregister_application(app2);
return ast_unregister_application(app);
}
int load_module(void)
{
ast_register_application(app2, setcallerid_pres_exec, synopsis2, descrip2);
return ast_register_application(app, setcallerid_exec, synopsis, descrip);
}
char *description(void)
{
return tdesc;
}
int usecount(void)
{
int res;
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -1,165 +0,0 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* Applictions connected with CDR engine
*
* Copyright (C) 2003, Digium
*
* Justin Huff <jjhuff@mspin.net>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*/
#include <sys/types.h>
#include <asterisk/channel.h>
#include <asterisk/cdr.h>
#include <asterisk/module.h>
#include <asterisk/pbx.h>
#include <asterisk/logger.h>
#include <asterisk/config.h>
#include <asterisk/manager.h>
#include <asterisk/utils.h>
#include <stdlib.h>
#include <string.h>
static char *tdesc = "CDR user field apps";
static char *setcdruserfield_descrip =
"[Synopsis]\n"
"SetCDRUserField(value)\n\n"
"[Description]\n"
"SetCDRUserField(value): Set the CDR 'user field' to value\n"
" The Call Data Record (CDR) user field is an extra field you\n"
" can use for data not stored anywhere else in the record.\n"
" CDR records can be used for billing or storing other arbitrary data\n"
" (I.E. telephone survey responses)\n"
" Also see AppendCDRUserField().\n"
" Always returns 0\n";
static char *setcdruserfield_app = "SetCDRUserField";
static char *setcdruserfield_synopsis = "Set the CDR user field";
static char *appendcdruserfield_descrip =
"[Synopsis]\n"
"AppendCDRUserField(value)\n\n"
"[Description]\n"
"AppendCDRUserField(value): Append value to the CDR user field\n"
" The Call Data Record (CDR) user field is an extra field you\n"
" can use for data not stored anywhere else in the record.\n"
" CDR records can be used for billing or storing other arbitrary data\n"
" (I.E. telephone survey responses)\n"
" Also see SetCDRUserField().\n"
" Always returns 0\n";
static char *appendcdruserfield_app = "AppendCDRUserField";
static char *appendcdruserfield_synopsis = "Append to the CDR user field";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
static int action_setcdruserfield(struct mansession *s, struct message *m)
{
struct ast_channel *c = NULL;
char *userfield = astman_get_header(m, "UserField");
char *channel = astman_get_header(m, "Channel");
char *append = astman_get_header(m, "Append");
if (ast_strlen_zero(channel)) {
astman_send_error(s, m, "No Channel specified");
return 0;
}
if (ast_strlen_zero(userfield)) {
astman_send_error(s, m, "No UserField specified");
return 0;
}
c = ast_channel_walk_locked(NULL);
while (c) {
if (!strcasecmp(c->name, channel))
break;
ast_mutex_unlock(&c->lock);
c = ast_channel_walk_locked(c);
}
if (!c) {
astman_send_error(s, m, "No such channel");
return 0;
}
if (ast_true(append))
ast_cdr_appenduserfield(c, userfield);
else
ast_cdr_setuserfield(c, userfield);
ast_mutex_unlock(&c->lock);
astman_send_ack(s, m, "CDR Userfield Set");
return 0;
}
static int setcdruserfield_exec(struct ast_channel *chan, void *data)
{
struct localuser *u;
int res = 0;
LOCAL_USER_ADD(u)
if (chan->cdr && data)
{
ast_cdr_setuserfield(chan, (char*)data);
}
LOCAL_USER_REMOVE(u);
return res;
}
static int appendcdruserfield_exec(struct ast_channel *chan, void *data)
{
struct localuser *u;
int res = 0;
LOCAL_USER_ADD(u)
if (chan->cdr && data)
{
ast_cdr_appenduserfield(chan, (char*)data);
}
LOCAL_USER_REMOVE(u);
return res;
}
int unload_module(void)
{
int res;
STANDARD_HANGUP_LOCALUSERS;
res = ast_unregister_application(setcdruserfield_app);
res |= ast_unregister_application(appendcdruserfield_app);
ast_manager_unregister("SetCDRUserField");
return res;
}
int load_module(void)
{
int res;
res = ast_register_application(setcdruserfield_app, setcdruserfield_exec, setcdruserfield_synopsis, setcdruserfield_descrip);
res |= ast_register_application(appendcdruserfield_app, appendcdruserfield_exec, appendcdruserfield_synopsis, appendcdruserfield_descrip);
ast_manager_register("SetCDRUserField", EVENT_FLAG_CALL, action_setcdruserfield, "Set the CDR UserField");
return res;
}
char *description(void)
{
return tdesc;
}
int usecount(void)
{
int res;
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -1,107 +0,0 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* App to set callerid
*
* Copyright (C) 1999, Mark Spencer
*
* Mark Spencer <markster@linux-support.net>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*/
#include <asterisk/lock.h>
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <asterisk/pbx.h>
#include <asterisk/module.h>
#include <asterisk/translate.h>
#include <asterisk/image.h>
#include <asterisk/callerid.h>
#include <asterisk/utils.h>
#include <string.h>
#include <stdlib.h>
static char *tdesc = "Set CallerID Name";
static char *app = "SetCIDName";
static char *synopsis = "Set CallerID Name";
static char *descrip =
" SetCIDName(cname[|a]): Set Caller*ID Name on a call to a new\n"
"value, while preserving the original Caller*ID number. This is\n"
"useful for providing additional information to the called\n"
"party. Sets ANI as well if a flag is used. Always returns 0\n";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
static int setcallerid_exec(struct ast_channel *chan, void *data)
{
int res = 0;
char tmp[256] = "";
char oldcid[256] = "", *l, *n;
char newcid[256] = "";
struct localuser *u;
char *opt;
int anitoo = 0;
if (data)
strncpy(tmp, (char *)data, sizeof(tmp) - 1);
opt = strchr(tmp, '|');
if (opt) {
*opt = '\0';
opt++;
if (*opt == 'a')
anitoo = 1;
}
LOCAL_USER_ADD(u);
if (chan->callerid) {
strncpy(oldcid, chan->callerid, sizeof(oldcid) - 1);
ast_callerid_parse(oldcid, &n, &l);
n = tmp;
if (!ast_strlen_zero(n)) {
if (l && !ast_strlen_zero(l))
snprintf(newcid, sizeof(newcid), "\"%s\" <%s>", n, l);
else
strncpy(newcid, tmp, sizeof(newcid) - 1);
} else if (l && !ast_strlen_zero(l)) {
strncpy(newcid, l, sizeof(newcid) - 1);
}
} else
strncpy(newcid, tmp, sizeof(newcid) - 1);
ast_set_callerid(chan, !ast_strlen_zero(newcid) ? newcid : NULL, anitoo);
LOCAL_USER_REMOVE(u);
return res;
}
int unload_module(void)
{
STANDARD_HANGUP_LOCALUSERS;
return ast_unregister_application(app);
}
int load_module(void)
{
return ast_register_application(app, setcallerid_exec, synopsis, descrip);
}
char *description(void)
{
return tdesc;
}
int usecount(void)
{
int res;
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -1,108 +0,0 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* App to set callerid
*
* Copyright (C) 1999, Mark Spencer
*
* Mark Spencer <markster@linux-support.net>
* Oliver Daudey <traveler@xs4all.nl>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*/
#include <asterisk/lock.h>
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <asterisk/pbx.h>
#include <asterisk/module.h>
#include <asterisk/translate.h>
#include <asterisk/image.h>
#include <asterisk/callerid.h>
#include <asterisk/utils.h>
#include <string.h>
#include <stdlib.h>
static char *tdesc = "Set CallerID Number";
static char *app = "SetCIDNum";
static char *synopsis = "Set CallerID Number";
static char *descrip =
" SetCIDNum(cnum[|a]): Set Caller*ID Number on a call to a new\n"
"value, while preserving the original Caller*ID name. This is\n"
"useful for providing additional information to the called\n"
"party. Sets ANI as well if a flag is used. Always returns 0\n";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
static int setcallerid_exec(struct ast_channel *chan, void *data)
{
int res = 0;
char tmp[256] = "";
char oldcid[256] = "", *l, *n;
char newcid[256] = "";
struct localuser *u;
char *opt;
int anitoo = 0;
if (data)
strncpy(tmp, (char *)data, sizeof(tmp) - 1);
opt = strchr(tmp, '|');
if (opt) {
*opt = '\0';
opt++;
if (*opt == 'a')
anitoo = 1;
}
LOCAL_USER_ADD(u);
if (chan->callerid) {
strncpy(oldcid, chan->callerid, sizeof(oldcid) - 1);
ast_callerid_parse(oldcid, &n, &l);
l = tmp;
if (!ast_strlen_zero(l)) {
if (n && !ast_strlen_zero(n))
snprintf(newcid, sizeof(newcid), "\"%s\" <%s>", n, l);
else
strncpy(newcid, tmp, sizeof(newcid) - 1);
} else if (n && !ast_strlen_zero(n)) {
strncpy(newcid, n, sizeof(newcid) - 1);
}
} else
strncpy(newcid, tmp, sizeof(newcid) - 1);
ast_set_callerid(chan, !ast_strlen_zero(newcid) ? newcid : NULL, anitoo);
LOCAL_USER_REMOVE(u);
return res;
}
int unload_module(void)
{
STANDARD_HANGUP_LOCALUSERS;
return ast_unregister_application(app);
}
int load_module(void)
{
return ast_register_application(app, setcallerid_exec, synopsis, descrip);
}
char *description(void)
{
return tdesc;
}
int usecount(void)
{
int res;
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -16,16 +16,17 @@
#include <asterisk/channel.h>
#include <asterisk/pbx.h>
#include <asterisk/module.h>
#include <asterisk/lock.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
static char *tdesc = "Trivial skeleton Application";
static char *app = "skel";
static char *synopsis =
" This is a skeleton application that shows you the basic structure to create your\n"
"own asterisk applications.\n";
STANDARD_LOCAL_USER;
@@ -53,7 +54,7 @@ int unload_module(void)
int load_module(void)
{
return ast_register_application(app, skel_exec, synopsis, tdesc);
return ast_register_application(app, skel_exec);
}
char *description(void)
@@ -67,8 +68,3 @@ int usecount(void)
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,89 +0,0 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* SoftHangup application
*
* Copyright (C) 1999, Mark Spencer
*
* Mark Spencer <markster@linux-support.net>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*/
#include <sys/types.h>
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <asterisk/pbx.h>
#include <asterisk/module.h>
#include <asterisk/lock.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
static char *synopsis = "Soft Hangup Application";
static char *tdesc = "Hangs up the requested channel";
static char *desc = " SoftHangup(Technology/resource)\n"
"Hangs up the requested channel. Always returns 0\n";
static char *app = "SoftHangup";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
static int softhangup_exec(struct ast_channel *chan, void *data)
{
struct localuser *u;
struct ast_channel *c=NULL;
if (!data) {
ast_log(LOG_WARNING, "SoftHangup requires an argument (Technology/resource)\n");
return 0;
}
LOCAL_USER_ADD(u);
c = ast_channel_walk_locked(NULL);
while (c) {
if (!strcasecmp(c->name, data)) {
ast_softhangup(c, AST_SOFTHANGUP_EXPLICIT);
ast_mutex_unlock(&c->lock);
break;
}
ast_mutex_unlock(&c->lock);
c = ast_channel_walk_locked(c);
}
LOCAL_USER_REMOVE(u);
return 0;
}
int unload_module(void)
{
STANDARD_HANGUP_LOCALUSERS;
return ast_unregister_application(app);
}
int load_module(void)
{
return ast_register_application(app, softhangup_exec, synopsis, desc);
}
char *description(void)
{
return tdesc;
}
int usecount(void)
{
int res;
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -1,564 +0,0 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* Connect to PostgreSQL
*
* Copyright (C) 2002, Christos Ricudis
*
* Christos Ricudis <ricudis@itc.auth.gr>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*/
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <asterisk/pbx.h>
#include <asterisk/module.h>
#include <asterisk/linkedlists.h>
#include <asterisk/chanvars.h>
#include <asterisk/lock.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
#include "libpq-fe.h"
#define EXTRA_LOG 0
static char *tdesc = "Simple PostgreSQL Interface";
static char *app = "PGSQL";
static char *synopsis = "Do several SQLy things";
static char *descrip =
"PGSQL(): Do several SQLy things\n"
"Syntax:\n"
" PGSQL(Connect var option-string)\n"
" Connects to a database. Option string contains standard PostgreSQL\n"
" parameters like host=, dbname=, user=. Connection identifer returned\n"
" in ${var}\n"
" PGSQL(Query var ${connection_identifier} query-string)\n"
" Executes standard SQL query contained in query-string using established\n"
" connection identified by ${connection_identifier}. Reseult of query is\n"
" is stored in ${var}.\n"
" PGSQL(Fetch statusvar ${result_identifier} var1 var2 ... varn)\n"
" Fetches a single row from a result set contained in ${result_identifier}.\n"
" Assigns returned fields to ${var1} ... ${varn}. ${statusvar} is set TRUE\n"
" if additional rows exist in reseult set.\n"
" PGSQL(Clear ${result_identifier})\n"
" Frees memory and datastructures associated with result set.\n"
" PGSQL(Disconnect ${connection_identifier})\n"
" Disconnects from named connection to PostgreSQL.\n" ;
/*
Syntax of SQL commands :
Connect var option-string
Connects to a database using the option-string and stores the
connection identifier in ${var}
Query var ${connection_identifier} query-string
Submits query-string to database backend and stores the result
identifier in ${var}
Fetch statusvar ${result_identifier} var1 var2 var3 ... varn
Fetches a row from the query and stores end-of-table status in
${statusvar} and columns in ${var1}..${varn}
Clear ${result_identifier}
Clears data structures associated with ${result_identifier}
Disconnect ${connection_identifier}
Disconnects from named connection
EXAMPLES OF USE :
exten => s,2,PGSQL(Connect connid host=localhost user=asterisk dbname=credit)
exten => s,3,PGSQL(Query resultid ${connid} SELECT username,credit FROM credit WHERE callerid=${CALLERIDNUM})
exten => s,4,PGSQL(Fetch fetchid ${resultid} datavar1 datavar2)
exten => s,5,GotoIf(${fetchid}?6:8)
exten => s,6,Festival("User ${datavar1} currently has credit balance of ${datavar2} dollars.")
exten => s,7,Goto(s,4)
exten => s,8,PGSQL(Clear ${resultid})
exten => s,9,PGSQL(Disconnect ${connid})
*/
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
extern void pbx_builtin_setvar_helper(struct ast_channel *chan, char *name, char *value);
#define AST_PGSQL_ID_DUMMY 0
#define AST_PGSQL_ID_CONNID 1
#define AST_PGSQL_ID_RESID 2
#define AST_PGSQL_ID_FETCHID 3
struct ast_PGSQL_id {
int identifier_type; /* 0=dummy, 1=connid, 2=resultid */
int identifier;
void *data;
AST_LIST_ENTRY(ast_PGSQL_id) entries;
} *ast_PGSQL_id;
AST_LIST_HEAD(PGSQLidshead,ast_PGSQL_id) PGSQLidshead;
static void *find_identifier(int identifier,int identifier_type) {
struct PGSQLidshead *headp;
struct ast_PGSQL_id *i;
void *res=NULL;
int found=0;
headp=&PGSQLidshead;
if (AST_LIST_LOCK(headp)) {
ast_log(LOG_WARNING,"Unable to lock identifiers list\n");
} else {
AST_LIST_TRAVERSE(headp,i,entries) {
if ((i->identifier==identifier) && (i->identifier_type==identifier_type)) {
found=1;
res=i->data;
break;
}
}
if (!found) {
ast_log(LOG_WARNING,"Identifier %d, identifier_type %d not found in identifier list\n",identifier,identifier_type);
}
AST_LIST_UNLOCK(headp);
}
return(res);
}
static int add_identifier(int identifier_type,void *data) {
struct ast_PGSQL_id *i,*j;
struct PGSQLidshead *headp;
int maxidentifier=0;
headp=&PGSQLidshead;
i=NULL;
j=NULL;
if (AST_LIST_LOCK(headp)) {
ast_log(LOG_WARNING,"Unable to lock identifiers list\n");
return(-1);
} else {
i=malloc(sizeof(struct ast_PGSQL_id));
AST_LIST_TRAVERSE(headp,j,entries) {
if (j->identifier>maxidentifier) {
maxidentifier=j->identifier;
}
}
i->identifier=maxidentifier+1;
i->identifier_type=identifier_type;
i->data=data;
AST_LIST_INSERT_HEAD(headp,i,entries);
AST_LIST_UNLOCK(headp);
}
return(i->identifier);
}
static int del_identifier(int identifier,int identifier_type) {
struct ast_PGSQL_id *i;
struct PGSQLidshead *headp;
int found=0;
headp=&PGSQLidshead;
if (AST_LIST_LOCK(headp)) {
ast_log(LOG_WARNING,"Unable to lock identifiers list\n");
} else {
AST_LIST_TRAVERSE(headp,i,entries) {
if ((i->identifier==identifier) &&
(i->identifier_type==identifier_type)) {
AST_LIST_REMOVE(headp,i,ast_PGSQL_id,entries);
free(i);
found=1;
break;
}
}
AST_LIST_UNLOCK(headp);
}
if (found==0) {
ast_log(LOG_WARNING,"Could not find identifier %d, identifier_type %d in list to delete\n",identifier,identifier_type);
return(-1);
} else {
return(0);
}
}
static int aPGSQL_connect(struct ast_channel *chan, void *data) {
char *s1;
char s[100] = "";
char *optionstring;
char *var;
int l;
int res;
PGconn *karoto;
int id;
char *stringp=NULL;
res=0;
l=strlen(data)+2;
s1=malloc(l);
strncpy(s1, data, l -1);
stringp=s1;
strsep(&stringp," "); // eat the first token, we already know it :P
var=strsep(&stringp," ");
optionstring=strsep(&stringp,"\n");
karoto = PQconnectdb(optionstring);
if (PQstatus(karoto) == CONNECTION_BAD) {
ast_log(LOG_WARNING,"Connection to database using '%s' failed. postgress reports : %s\n", optionstring,
PQerrorMessage(karoto));
res=-1;
} else {
ast_log(LOG_WARNING,"adding identifier\n");
id=add_identifier(AST_PGSQL_ID_CONNID,karoto);
snprintf(s, sizeof(s), "%d", id);
pbx_builtin_setvar_helper(chan,var,s);
}
free(s1);
return res;
}
static int aPGSQL_query(struct ast_channel *chan, void *data) {
char *s1,*s2,*s3,*s4;
char s[100] = "";
char *querystring;
char *var;
int l;
int res,nres;
PGconn *karoto;
PGresult *PGSQLres;
int id,id1;
char *stringp=NULL;
res=0;
l=strlen(data)+2;
s1=malloc(l);
s2=malloc(l);
strncpy(s1, data, l - 1);
stringp=s1;
strsep(&stringp," "); // eat the first token, we already know it :P
s3=strsep(&stringp," ");
while (1) { // ugly trick to make branches with break;
var=s3;
s4=strsep(&stringp," ");
id=atoi(s4);
querystring=strsep(&stringp,"\n");
if ((karoto=find_identifier(id,AST_PGSQL_ID_CONNID))==NULL) {
ast_log(LOG_WARNING,"Invalid connection identifier %d passed in aPGSQL_query\n",id);
res=-1;
break;
}
PGSQLres=PQexec(karoto,querystring);
if (PGSQLres==NULL) {
ast_log(LOG_WARNING,"aPGSQL_query: Connection Error (connection identifier = %d, error message : %s)\n",id,PQerrorMessage(karoto));
res=-1;
break;
}
if (PQresultStatus(PGSQLres) == PGRES_BAD_RESPONSE ||
PQresultStatus(PGSQLres) == PGRES_NONFATAL_ERROR ||
PQresultStatus(PGSQLres) == PGRES_FATAL_ERROR) {
ast_log(LOG_WARNING,"aPGSQL_query: Query Error (connection identifier : %d, error message : %s)\n",id,PQcmdStatus(PGSQLres));
res=-1;
break;
}
nres=PQnfields(PGSQLres);
id1=add_identifier(AST_PGSQL_ID_RESID,PGSQLres);
snprintf(s, sizeof(s), "%d", id1);
pbx_builtin_setvar_helper(chan,var,s);
break;
}
free(s1);
free(s2);
return(res);
}
static int aPGSQL_fetch(struct ast_channel *chan, void *data) {
char *s1,*s2,*fetchid_var,*s4,*s5,*s6,*s7;
char s[100];
char *var;
int l;
int res;
PGresult *PGSQLres;
int id,id1,i,j,fnd;
int *lalares=NULL;
int nres;
struct ast_var_t *variables;
struct varshead *headp;
char *stringp=NULL;
headp=&chan->varshead;
res=0;
l=strlen(data)+2;
s7=NULL;
s1=malloc(l);
s2=malloc(l);
strncpy(s1, data, l - 1);
stringp=s1;
strsep(&stringp," "); // eat the first token, we already know it :P
fetchid_var=strsep(&stringp," ");
while (1) { // ugly trick to make branches with break;
var=fetchid_var; // fetchid
fnd=0;
AST_LIST_TRAVERSE(headp,variables,entries) {
if (strncasecmp(ast_var_name(variables),fetchid_var,strlen(fetchid_var))==0) {
s7=ast_var_value(variables);
fnd=1;
break;
}
}
if (fnd==0) {
s7="0";
pbx_builtin_setvar_helper(chan,fetchid_var,s7);
}
s4=strsep(&stringp," ");
id=atoi(s4); // resultid
if ((PGSQLres=find_identifier(id,AST_PGSQL_ID_RESID))==NULL) {
ast_log(LOG_WARNING,"Invalid result identifier %d passed in aPGSQL_fetch\n",id);
res=-1;
break;
}
id=atoi(s7); //fetchid
if ((lalares=find_identifier(id,AST_PGSQL_ID_FETCHID))==NULL) {
i=0; // fetching the very first row
} else {
i=*lalares;
free(lalares);
del_identifier(id,AST_PGSQL_ID_FETCHID); // will re-add it a bit later
}
if (i<PQntuples(PGSQLres)) {
nres=PQnfields(PGSQLres);
ast_log(LOG_WARNING,"ast_PGSQL_fetch : nres = %d i = %d ;\n",nres,i);
for (j=0;j<nres;j++) {
s5=strsep(&stringp," ");
if (s5==NULL) {
ast_log(LOG_WARNING,"ast_PGSQL_fetch : More tuples (%d) than variables (%d)\n",nres,j);
break;
}
s6=PQgetvalue(PGSQLres,i,j);
if (s6==NULL) {
ast_log(LOG_WARNING,"PWgetvalue(res,%d,%d) returned NULL in ast_PGSQL_fetch\n",i,j);
break;
}
ast_log(LOG_WARNING,"===setting variable '%s' to '%s'\n",s5,s6);
pbx_builtin_setvar_helper(chan,s5,s6);
}
lalares=malloc(sizeof(int));
*lalares = ++i; // advance to the next row
id1 = add_identifier(AST_PGSQL_ID_FETCHID,lalares);
} else {
ast_log(LOG_WARNING,"ast_PGSQL_fetch : EOF\n");
id1 = 0; // no more rows
}
snprintf(s, sizeof(s), "%d", id1);
ast_log(LOG_WARNING,"Setting var '%s' to value '%s'\n",fetchid_var,s);
pbx_builtin_setvar_helper(chan,fetchid_var,s);
break;
}
free(s1);
free(s2);
return(res);
}
static int aPGSQL_reset(struct ast_channel *chan, void *data) {
char *s1,*s3;
int l;
PGconn *karoto;
int id;
char *stringp=NULL;
l=strlen(data)+2;
s1=malloc(l);
strncpy(s1, data, l - 1);
stringp=s1;
strsep(&stringp," "); // eat the first token, we already know it :P
s3=strsep(&stringp," ");
id=atoi(s3);
if ((karoto=find_identifier(id,AST_PGSQL_ID_CONNID))==NULL) {
ast_log(LOG_WARNING,"Invalid connection identifier %d passed in aPGSQL_reset\n",id);
} else {
PQreset(karoto);
}
free(s1);
return(0);
}
static int aPGSQL_clear(struct ast_channel *chan, void *data) {
char *s1,*s3;
int l;
PGresult *karoto;
int id;
char *stringp=NULL;
l=strlen(data)+2;
s1=malloc(l);
strncpy(s1, data, l - 1);
stringp=s1;
strsep(&stringp," "); // eat the first token, we already know it :P
s3=strsep(&stringp," ");
id=atoi(s3);
if ((karoto=find_identifier(id,AST_PGSQL_ID_RESID))==NULL) {
ast_log(LOG_WARNING,"Invalid result identifier %d passed in aPGSQL_clear\n",id);
} else {
PQclear(karoto);
del_identifier(id,AST_PGSQL_ID_RESID);
}
free(s1);
return(0);
}
static int aPGSQL_disconnect(struct ast_channel *chan, void *data) {
char *s1,*s3;
int l;
PGconn *karoto;
int id;
char *stringp=NULL;
l=strlen(data)+2;
s1=malloc(l);
strncpy(s1, data, l - 1);
stringp=s1;
strsep(&stringp," "); // eat the first token, we already know it :P
s3=strsep(&stringp," ");
id=atoi(s3);
if ((karoto=find_identifier(id,AST_PGSQL_ID_CONNID))==NULL) {
ast_log(LOG_WARNING,"Invalid connection identifier %d passed in aPGSQL_disconnect\n",id);
} else {
PQfinish(karoto);
del_identifier(id,AST_PGSQL_ID_CONNID);
}
free(s1);
return(0);
}
static int aPGSQL_debug(struct ast_channel *chan, void *data) {
ast_log(LOG_WARNING,"Debug : %s\n",(char *)data);
return(0);
}
static int PGSQL_exec(struct ast_channel *chan, void *data)
{
struct localuser *u;
int result;
#if EXTRA_LOG
printf("PRSQL_exec: data=%s\n",(char*)data);
#endif
if (!data) {
ast_log(LOG_WARNING, "APP_PGSQL requires an argument (see manual)\n");
return -1;
}
LOCAL_USER_ADD(u);
result=0;
if (strncasecmp("connect",data,strlen("connect"))==0) {
result=(aPGSQL_connect(chan,data));
} else if (strncasecmp("query",data,strlen("query"))==0) {
result=(aPGSQL_query(chan,data));
} else if (strncasecmp("fetch",data,strlen("fetch"))==0) {
result=(aPGSQL_fetch(chan,data));
} else if (strncasecmp("reset",data,strlen("reset"))==0) {
result=(aPGSQL_reset(chan,data));
} else if (strncasecmp("clear",data,strlen("clear"))==0) {
result=(aPGSQL_clear(chan,data));
} else if (strncasecmp("debug",data,strlen("debug"))==0) {
result=(aPGSQL_debug(chan,data));
} else if (strncasecmp("disconnect",data,strlen("disconnect"))==0) {
result=(aPGSQL_disconnect(chan,data));
} else {
ast_log(LOG_WARNING, "Unknown APP_PGSQL argument : %s\n",(char *)data);
result=-1;
}
LOCAL_USER_REMOVE(u);
return result;
}
int unload_module(void)
{
STANDARD_HANGUP_LOCALUSERS;
return ast_unregister_application(app);
}
int load_module(void)
{
struct PGSQLidshead *headp;
headp=&PGSQLidshead;
AST_LIST_HEAD_INIT(headp);
return ast_register_application(app, PGSQL_exec, synopsis, descrip);
}
char *description(void)
{
return tdesc;
}
int usecount(void)
{
int res;
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -1,97 +0,0 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* Skeleton application
*
* Copyright (C) 1999, Mark Spencer
*
* Mark Spencer <markster@linux-support.net>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*/
#include <sys/types.h>
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <asterisk/pbx.h>
#include <asterisk/module.h>
#include <asterisk/lock.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
static char *tdesc = "Strip trailing digits";
static char *descrip =
" StripLSD(count): Strips the trailing 'count' digits from the channel's\n"
"associated extension. For example, the number 5551212 when stripped with a\n"
"count of 4 would be changed to 555. This app always returns 0, and the PBX\n"
"will continue processing at the next priority for the *new* extension.\n"
" So, for example, if priority 3 of 5551212 is StripLSD 4, the next step\n"
"executed will be priority 4 of 555. If you switch into an extension which\n"
"has no first step, the PBX will treat it as though the user dialed an\n"
"invalid extension.\n";
static char *app = "StripLSD";
static char *synopsis = "Strip Least Significant Digits";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
static int striplsd_exec(struct ast_channel *chan, void *data)
{
char newexten[AST_MAX_EXTENSION] = "";
int maxbytes = 0;
int stripcount = 0;
int extlen = strlen(chan->exten);
maxbytes = sizeof(newexten) - 1;
if (data) {
stripcount = atoi(data);
}
if (!stripcount) {
ast_log(LOG_DEBUG, "Ignoring, since number of digits to strip is 0\n");
return 0;
}
if (extlen > stripcount) {
if (extlen - stripcount <= maxbytes) {
maxbytes = extlen - stripcount;
}
strncpy(newexten, chan->exten, maxbytes);
}
strncpy(chan->exten, newexten, sizeof(chan->exten)-1);
return 0;
}
int unload_module(void)
{
STANDARD_HANGUP_LOCALUSERS;
return ast_unregister_application(app);
}
int load_module(void)
{
return ast_register_application(app, striplsd_exec, synopsis, descrip);
}
char *description(void)
{
return tdesc;
}
int usecount(void)
{
int res;
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -1,134 +0,0 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* Skeleton application
*
* Copyright (C) 1999, Mark Spencer
*
* Mark Spencer <markster@linux-support.net>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*/
#include <sys/types.h>
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <asterisk/pbx.h>
#include <asterisk/module.h>
#include <asterisk/pbx.h>
#include <asterisk/lock.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
static char *tdesc = "(Deprecated) Save substring digits in a given variable";
static char *descrip =
" (Deprecated, use ${variable:a:b} instead)\n"
"\n"
" SubString(variable=string_of_digits|count1|count2): Assigns the substring\n"
"of string_of_digits to a given variable. Parameter count1 may be positive\n"
"or negative. If it's positive then we skip the first count1 digits from the\n"
"left. If it's negative, we move count1 digits counting from the end of\n"
"the string to the left. Parameter count2 implies how many digits we are\n"
"taking from the point that count1 placed us. If count2 is negative, then\n"
"that many digits are omitted from the end.\n"
"For example:\n"
"exten => _NXXXXXX,1,SubString,test=2564286161|0|3\n"
"assigns the area code (3 first digits) to variable test.\n"
"exten => _NXXXXXX,1,SubString,test=2564286161|-7|7\n"
"assigns the last 7 digits to variable test.\n"
"exten => _NXXXXXX,1,SubString,test=2564286161|0|-4\n"
"assigns all but the last 4 digits to variable test.\n"
"If there are no parameters it'll return with -1.\n"
"If there wrong parameters it go on and return with 0\n";
static char *app = "SubString";
static char *synopsis = "(Deprecated) Save substring digits in a given variable";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
static int substring_exec(struct ast_channel *chan, void *data)
{
char newexten[AST_MAX_EXTENSION] = "";
char *count1, *count2;
char *first, *second, *stringp;
stringp=alloca(strlen(data)+1);
ast_log(LOG_WARNING, "The use of Substring application is deprecated. Please use ${variable:a:b} instead\n");
strncpy(stringp,data,strlen(data));
if (strchr(stringp,'|')&&strchr(stringp,'=')) {
int icount1,icount2;
first=strsep(&stringp,"=");
second=strsep(&stringp,"|");
count1=strsep(&stringp,"|");
count2=strsep(&stringp,"\0");
if (!first || !second || !count1 || !count2) {
ast_log(LOG_DEBUG, "Ignoring, since there is no argument: variable or string or count1 or count2\n");
return 0;
}
icount1=atoi(count1);
icount2=atoi(count2);
if (icount2<0) {
icount2 = icount2 + strlen(second);
}
if (abs(icount1)>strlen(second)) {
ast_log(LOG_WARNING, "Limiting count1 parameter because it exceeds the length of the string\n");
if (icount1>=0)
icount1=strlen(second);
else
icount1=0;
}
if ((icount1<0 && icount2>-icount1) || (icount1>=0 && icount1+icount2>strlen(second))) {
ast_log(LOG_WARNING, "Limiting count2 parameter because it exceeds the length of the string\n");
if (icount1>=0)
icount2=strlen(second)-icount1;
else
icount2=strlen(second)+icount1;
}
if (first&&second) {
if (icount1>=0)
strncpy(newexten,second+icount1,icount2);
else
strncpy(newexten,second+strlen(second)+icount1,icount2);
pbx_builtin_setvar_helper(chan,first,newexten);
}
} else {
ast_log(LOG_DEBUG, "Ignoring, no parameters\n");
}
return 0;
}
int unload_module(void)
{
STANDARD_HANGUP_LOCALUSERS;
return ast_unregister_application(app);
}
int load_module(void)
{
return ast_register_application(app, substring_exec, synopsis, descrip);
}
char *description(void)
{
return tdesc;
}
int usecount(void)
{
int res;
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -3,76 +3,54 @@
*
* Execute arbitrary system commands
*
* Copyright (C) 1999-2004, Digium, Inc.
* Copyright (C) 1999, Mark Spencer
*
* Mark Spencer <markster@digium.com>
* Mark Spencer <markster@linux-support.net>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*/
#include <asterisk/lock.h>
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <asterisk/pbx.h>
#include <asterisk/module.h>
#include <asterisk/app.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <pthread.h>
static char *tdesc = "Generic System() application";
static char *app = "System";
static char *app2 = "TrySystem";
static char *synopsis = "Execute a system command";
static char *synopsis2 = "Try executing a system command";
static char *descrip =
" System(command): Executes a command by using system(). Returns -1 on\n"
"failure to execute the specified command. If the command itself executes\n"
"but is in error, and if there exists a priority n + 101, where 'n' is the\n"
"priority of the current instance, then the channel will be setup to\n"
"continue at that priority level. Otherwise, System returns 0.\n";
static char *descrip2 =
" TrySystem(command): Executes a command by using system(). Returns 0\n"
"on any situation. If the command itself executes but is in error, and if\n"
"there exists a priority n + 101, where 'n' is the priority of the current\n"
"instance, then the channel will be setup to continue at that\n"
"priority level. Otherwise, System returns 0.\n";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
static int system_exec_helper(struct ast_channel *chan, void *data, int failmode)
static int skel_exec(struct ast_channel *chan, void *data)
{
int res=0;
struct localuser *u;
if (!data) {
ast_log(LOG_WARNING, "System requires an argument(command)\n");
return failmode;
return -1;
}
LOCAL_USER_ADD(u);
/* Do our thing here */
res = ast_safe_system((char *)data);
if ((res < 0) && (errno != ECHILD)) {
ast_log(LOG_WARNING, "Unable to execute '%s'\n", (char *)data);
res = failmode;
res = system((char *)data);
if (res < 0) {
ast_log(LOG_WARNING, "Unable to execute '%s'\n", data);
res = -1;
} else if (res == 127) {
ast_log(LOG_WARNING, "Unable to execute '%s'\n", (char *)data);
res = failmode;
ast_log(LOG_WARNING, "Unable to execute '%s'\n", data);
res = -1;
} else {
if (res < 0)
res = 0;
if (res && ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 101, chan->callerid))
if (res && ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 101))
chan->priority+=100;
res = 0;
}
@@ -80,27 +58,15 @@ static int system_exec_helper(struct ast_channel *chan, void *data, int failmode
return res;
}
static int system_exec(struct ast_channel *chan, void *data)
{
return system_exec_helper(chan, data, -1);
}
static int trysystem_exec(struct ast_channel *chan, void *data)
{
return system_exec_helper(chan, data, 0);
}
int unload_module(void)
{
STANDARD_HANGUP_LOCALUSERS;
ast_unregister_application(app2);
return ast_unregister_application(app);
}
int load_module(void)
{
ast_register_application(app2, trysystem_exec, synopsis2, descrip2);
return ast_register_application(app, system_exec, synopsis, descrip);
return ast_register_application(app, skel_exec);
}
char *description(void)
@@ -114,8 +80,3 @@ int usecount(void)
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -1,218 +0,0 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* Playback a file with audio detect
*
* Copyright (C) 2004, Digium, Inc.
*
* Mark Spencer <markster@digium.com>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*/
#include <asterisk/lock.h>
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <asterisk/pbx.h>
#include <asterisk/module.h>
#include <asterisk/translate.h>
#include <asterisk/utils.h>
#include <asterisk/dsp.h>
#include <string.h>
#include <stdlib.h>
static char *tdesc = "Playback with Talk Detection";
static char *app = "BackgroundDetect";
static char *synopsis = "Background a file with talk detect";
static char *descrip =
" BackgroundDetect(filename[|sil[|min|[max]]]): Plays back a given\n"
"filename, waiting for interruption from a given digit (the digit must\n"
"start the beginning of a valid extension, or it will be ignored).\n"
"During the playback of the file, audio is monitored in the receive\n"
"direction, and if a period of non-silence which is greater than 'min' ms\n"
"yet less than 'max' ms is followed by silence for at least 'sil' ms then\n"
"the audio playback is aborted and processing jumps to the 'talk' extension\n"
"if available. If unspecified, sil, min, and max default to 1000, 100, and\n"
"infinity respectively. Returns -1 on hangup, and 0 on successful playback\n"
"completion with no exit conditions.\n";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
static int background_detect_exec(struct ast_channel *chan, void *data)
{
int res = 0;
struct localuser *u;
char tmp[256];
char *options;
char *stringp;
struct ast_frame *fr;
int notsilent=0;
struct timeval start = { 0, 0}, end = {0, 0};
int sil = 1000;
int min = 100;
int max = -1;
int x;
int origrformat=0;
struct ast_dsp *dsp;
if (!data || ast_strlen_zero((char *)data)) {
ast_log(LOG_WARNING, "BackgroundDetect requires an argument (filename)\n");
return -1;
}
strncpy(tmp, (char *)data, sizeof(tmp)-1);
stringp=tmp;
strsep(&stringp, "|");
options = strsep(&stringp, "|");
if (options) {
if ((sscanf(options, "%d", &x) == 1) && (x > 0))
sil = x;
options = strsep(&stringp, "|");
if (options) {
if ((sscanf(options, "%d", &x) == 1) && (x > 0))
min = x;
options = strsep(&stringp, "|");
if (options) {
if ((sscanf(options, "%d", &x) == 1) && (x > 0))
max = x;
}
}
}
ast_log(LOG_DEBUG, "Preparing detect of '%s', sil=%d,min=%d,max=%d\n",
tmp, sil, min, max);
LOCAL_USER_ADD(u);
if (chan->_state != AST_STATE_UP) {
/* Otherwise answer unless we're supposed to send this while on-hook */
res = ast_answer(chan);
}
if (!res) {
origrformat = chan->readformat;
if ((res = ast_set_read_format(chan, AST_FORMAT_SLINEAR)))
ast_log(LOG_WARNING, "Unable to set read format to linear!\n");
}
if (!(dsp = ast_dsp_new())) {
ast_log(LOG_WARNING, "Unable to allocate DSP!\n");
res = -1;
}
if (!res) {
ast_stopstream(chan);
res = ast_streamfile(chan, tmp, chan->language);
if (!res) {
while(chan->stream) {
res = ast_sched_wait(chan->sched);
if ((res < 0) && !chan->timingfunc) {
res = 0;
break;
}
if (res < 0)
res = 1000;
res = ast_waitfor(chan, res);
if (res < 0) {
ast_log(LOG_WARNING, "Waitfor failed on %s\n", chan->name);
break;
} else if (res > 0) {
fr = ast_read(chan);
if (!fr) {
res = -1;
break;
} else if (fr->frametype == AST_FRAME_DTMF) {
char t[2];
t[0] = fr->subclass;
t[1] = '\0';
if (ast_canmatch_extension(chan, chan->context, t, 1, chan->callerid)) {
/* They entered a valid extension, or might be anyhow */
res = fr->subclass;
ast_frfree(fr);
break;
}
} else if ((fr->frametype == AST_FRAME_VOICE) && (fr->subclass == AST_FORMAT_SLINEAR)) {
int totalsilence;
int ms;
res = ast_dsp_silence(dsp, fr, &totalsilence);
if (res && (totalsilence > sil)) {
/* We've been quiet a little while */
if (notsilent) {
/* We had heard some talking */
gettimeofday(&end, NULL);
ms = (end.tv_sec - start.tv_sec) * 1000;
ms += (end.tv_usec - start.tv_usec) / 1000;
ms -= sil;
if (ms < 0)
ms = 0;
if ((ms > min) && ((max < 0) || (ms < max))) {
ast_log(LOG_DEBUG, "Found qualified token of %d ms\n", ms);
if (ast_exists_extension(chan, chan->context, "talk", 1, chan->callerid)) {
strncpy(chan->exten, "talk", sizeof(chan->exten) -1 );
chan->priority = 0;
}
res = 0;
ast_frfree(fr);
break;
} else
ast_log(LOG_DEBUG, "Found unqualified token of %d ms\n", ms);
notsilent = 0;
}
} else {
if (!notsilent) {
/* Heard some audio, mark the begining of the token */
gettimeofday(&start, NULL);
ast_log(LOG_DEBUG, "Start of voice token!\n");
notsilent = 1;
}
}
}
ast_frfree(fr);
}
ast_sched_runq(chan->sched);
}
ast_stopstream(chan);
} else {
ast_log(LOG_WARNING, "ast_streamfile failed on %s for %s\n", chan->name, (char *)data);
res = 0;
}
}
if (res > -1) {
if (origrformat && ast_set_read_format(chan, origrformat)) {
ast_log(LOG_WARNING, "Failed to restore read format for %s to %s\n",
chan->name, ast_getformatname(origrformat));
}
}
if (dsp)
ast_dsp_free(dsp);
LOCAL_USER_REMOVE(u);
return res;
}
int unload_module(void)
{
STANDARD_HANGUP_LOCALUSERS;
return ast_unregister_application(app);
}
int load_module(void)
{
return ast_register_application(app, background_detect_exec, synopsis, descrip);
}
char *description(void)
{
return tdesc;
}
int usecount(void)
{
int res;
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -1,473 +0,0 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* Applications to test connection and produce report in text file
*
* Copyright (C) 2004, Digium, Inc.
*
* Mark Spencer <markster@digium.com>
* Russell Bryant <russelb@clemson.edu>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*/
#include <sys/types.h>
#include <asterisk/channel.h>
#include <asterisk/options.h>
#include <asterisk/module.h>
#include <asterisk/logger.h>
#include <asterisk/lock.h>
#include <asterisk/app.h>
#include <asterisk/pbx.h>
#include <asterisk/utils.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include "../astconf.h"
static char *tdesc = "Interface Test Application";
static char *tests_descrip =
"TestServer(): Perform test server function and write call report.\n"
"Results stored in /var/log/asterisk/testreports/<testid>-server.txt";
static char *tests_app = "TestServer";
static char *tests_synopsis = "Execute Interface Test Server";
static char *testc_descrip =
"TestClient(testid): Executes test client with given testid.\n"
"Results stored in /var/log/asterisk/testreports/<testid>-client.txt";
static char *testc_app = "TestClient";
static char *testc_synopsis = "Execute Interface Test Client";
static int measurenoise(struct ast_channel *chan, int ms, char *who)
{
int res=0;
int mssofar;
int noise=0;
int samples=0;
int x;
short *foo;
struct timeval start, tv;
struct ast_frame *f;
int rformat;
rformat = chan->readformat;
if (ast_set_read_format(chan, AST_FORMAT_SLINEAR)) {
ast_log(LOG_NOTICE, "Unable to set to linear mode!\n");
return -1;
}
gettimeofday(&start, NULL);
for(;;) {
gettimeofday(&tv, NULL);
mssofar = (tv.tv_sec - start.tv_sec) * 1000;
mssofar += (tv.tv_usec - start.tv_usec) / 1000;
if (mssofar > ms)
break;
res = ast_waitfor(chan, ms - mssofar);
if (res < 1)
break;
f = ast_read(chan);
if (!f) {
res = -1;
break;
}
if ((f->frametype == AST_FRAME_VOICE) && (f->subclass == AST_FORMAT_SLINEAR)) {
foo = (short *)f->data;
for (x=0;x<f->samples;x++) {
noise += abs(foo[x]);
samples++;
}
}
}
if (rformat) {
if (ast_set_read_format(chan, rformat)) {
ast_log(LOG_NOTICE, "Unable to restore original format!\n");
return -1;
}
}
if (res < 0)
return res;
if (!samples) {
ast_log(LOG_NOTICE, "No samples were received from the other side!\n");
return -1;
}
ast_log(LOG_DEBUG, "%s: Noise: %d, samples: %d, avg: %d\n", who, noise, samples, noise / samples);
return (noise / samples);
}
static int sendnoise(struct ast_channel *chan, int ms)
{
int res;
res = ast_tonepair_start(chan, 1537, 2195, ms, 8192);
if (!res) {
res = ast_waitfordigit(chan, ms);
ast_tonepair_stop(chan);
}
return res;
}
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
static int testclient_exec(struct ast_channel *chan, void *data)
{
struct localuser *u;
int res = 0;
char *testid=data;
char fn[80];
char serverver[80];
FILE *f;
LOCAL_USER_ADD(u);
/* Check for test id */
if (!testid || ast_strlen_zero(testid)) {
ast_log(LOG_WARNING, "TestClient requires an argument - the test id\n");
return -1;
}
if (chan->_state != AST_STATE_UP)
res = ast_answer(chan);
/* Wait a few just to be sure things get started */
res = ast_safe_sleep(chan, 3000);
/* Transmit client version */
if (!res)
res = ast_dtmf_stream(chan, NULL, "8378*1#", 0);
ast_log(LOG_DEBUG, "Transmit client version\n");
/* Read server version */
ast_log(LOG_DEBUG, "Read server version\n");
if (!res)
res = ast_app_getdata(chan, NULL, serverver, sizeof(serverver) - 1, 0);
if (res > 0)
res = 0;
ast_log(LOG_DEBUG, "server version: %s\n", serverver);
if (res > 0)
res = 0;
if (!res)
res = ast_safe_sleep(chan, 1000);
/* Send test id */
if (!res)
res = ast_dtmf_stream(chan, NULL, testid, 0);
if (!res)
res = ast_dtmf_stream(chan, NULL, "#", 0);
ast_log(LOG_DEBUG, "send test identifier: %s\n", testid);
if ((res >=0) && (!ast_strlen_zero(testid))) {
/* Make the directory to hold the test results in case it's not there */
snprintf(fn, sizeof(fn), "%s/testresults", ast_config_AST_LOG_DIR);
mkdir(fn, 0777);
snprintf(fn, sizeof(fn), "%s/testresults/%s-client.txt", ast_config_AST_LOG_DIR, testid);
if ((f = fopen(fn, "w+"))) {
setlinebuf(f);
fprintf(f, "CLIENTCHAN: %s\n", chan->name);
fprintf(f, "CLIENTTEST ID: %s\n", testid);
fprintf(f, "ANSWER: PASS\n");
res = 0;
if (!res) {
/* Step 1: Wait for "1" */
ast_log(LOG_DEBUG, "TestClient: 2. Wait DTMF 1\n");
res = ast_waitfordigit(chan, 3000);
fprintf(f, "WAIT DTMF 1: %s\n", (res != '1') ? "FAIL" : "PASS");
if (res == '1')
res = 0;
else
res = -1;
}
if (!res)
res = ast_safe_sleep(chan, 1000);
if (!res) {
/* Step 2: Send "2" */
ast_log(LOG_DEBUG, "TestClient: 2. Send DTMF 2\n");
res = ast_dtmf_stream(chan, NULL, "2", 0);
fprintf(f, "SEND DTMF 2: %s\n", (res < 0) ? "FAIL" : "PASS");
if (res > 0)
res = 0;
}
if (!res) {
/* Step 3: Wait one second */
ast_log(LOG_DEBUG, "TestClient: 3. Wait one second\n");
res = ast_safe_sleep(chan, 1000);
fprintf(f, "WAIT 1 SEC: %s\n", (res < 0) ? "FAIL" : "PASS");
if (res > 0)
res = 0;
}
if (!res) {
/* Step 4: Measure noise */
ast_log(LOG_DEBUG, "TestClient: 4. Measure noise\n");
res = measurenoise(chan, 5000, "TestClient");
fprintf(f, "MEASURENOISE: %s (%d)\n", (res < 0) ? "FAIL" : "PASS", res);
if (res > 0)
res = 0;
}
if (!res) {
/* Step 5: Wait for "4" */
ast_log(LOG_DEBUG, "TestClient: 5. Wait DTMF 4\n");
res = ast_waitfordigit(chan, 3000);
fprintf(f, "WAIT DTMF 4: %s\n", (res != '4') ? "FAIL" : "PASS");
if (res == '4')
res = 0;
else
res = -1;
}
if (!res) {
/* Step 6: Transmit tone noise */
ast_log(LOG_DEBUG, "TestClient: 6. Transmit tone\n");
res = sendnoise(chan, 6000);
fprintf(f, "SENDTONE: %s\n", (res < 0) ? "FAIL" : "PASS");
}
if (!res || (res == '5')) {
/* Step 7: Wait for "5" */
ast_log(LOG_DEBUG, "TestClient: 7. Wait DTMF 5\n");
if (!res)
res = ast_waitfordigit(chan, 3000);
fprintf(f, "WAIT DTMF 5: %s\n", (res != '5') ? "FAIL" : "PASS");
if (res == '5')
res = 0;
else
res = -1;
}
if (!res) {
/* Step 8: Wait one second */
ast_log(LOG_DEBUG, "TestClient: 8. Wait one second\n");
res = ast_safe_sleep(chan, 1000);
fprintf(f, "WAIT 1 SEC: %s\n", (res < 0) ? "FAIL" : "PASS");
if (res > 0)
res = 0;
}
if (!res) {
/* Step 9: Measure noise */
ast_log(LOG_DEBUG, "TestClient: 6. Measure tone\n");
res = measurenoise(chan, 4000, "TestClient");
fprintf(f, "MEASURETONE: %s (%d)\n", (res < 0) ? "FAIL" : "PASS", res);
if (res > 0)
res = 0;
}
if (!res) {
/* Step 10: Send "7" */
ast_log(LOG_DEBUG, "TestClient: 7. Send DTMF 7\n");
res = ast_dtmf_stream(chan, NULL, "7", 0);
fprintf(f, "SEND DTMF 7: %s\n", (res < 0) ? "FAIL" : "PASS");
if (res > 0)
res =0;
}
if (!res) {
/* Step 11: Wait for "8" */
ast_log(LOG_DEBUG, "TestClient: 11. Wait DTMF 8\n");
res = ast_waitfordigit(chan, 3000);
fprintf(f, "WAIT DTMF 8: %s\n", (res != '8') ? "FAIL" : "PASS");
if (res == '8')
res = 0;
else
res = -1;
}
if (!res) {
/* Step 12: Hangup! */
ast_log(LOG_DEBUG, "TestClient: 12. Hangup\n");
}
ast_log(LOG_DEBUG, "-- TEST COMPLETE--\n");
fprintf(f, "-- END TEST--\n");
fclose(f);
res = -1;
} else
res = -1;
} else {
ast_log(LOG_NOTICE, "Did not read a test ID on '%s'\n", chan->name);
res = -1;
}
LOCAL_USER_REMOVE(u);
return res;
}
static int testserver_exec(struct ast_channel *chan, void *data)
{
struct localuser *u;
int res = 0;
char testid[80]="";
char fn[80];
FILE *f;
LOCAL_USER_ADD(u);
if (chan->_state != AST_STATE_UP)
res = ast_answer(chan);
/* Read version */
ast_log(LOG_DEBUG, "Read client version\n");
if (!res)
res = ast_app_getdata(chan, NULL, testid, sizeof(testid) - 1, 0);
if (res > 0)
res = 0;
ast_log(LOG_DEBUG, "client version: %s\n", testid);
ast_log(LOG_DEBUG, "Transmit server version\n");
res = ast_safe_sleep(chan, 1000);
if (!res)
res = ast_dtmf_stream(chan, NULL, "8378*1#", 0);
if (res > 0)
res = 0;
if (!res)
res = ast_app_getdata(chan, NULL, testid, sizeof(testid) - 1, 0);
ast_log(LOG_DEBUG, "read test identifier: %s\n", testid);
/* Check for sneakyness */
if (strchr(testid, '/'))
res = -1;
if ((res >=0) && (!ast_strlen_zero(testid))) {
/* Got a Test ID! Whoo hoo! */
/* Make the directory to hold the test results in case it's not there */
snprintf(fn, sizeof(fn), "%s/testresults", ast_config_AST_LOG_DIR);
mkdir(fn, 0777);
snprintf(fn, sizeof(fn), "%s/testresults/%s-server.txt", ast_config_AST_LOG_DIR, testid);
if ((f = fopen(fn, "w+"))) {
setlinebuf(f);
fprintf(f, "SERVERCHAN: %s\n", chan->name);
fprintf(f, "SERVERTEST ID: %s\n", testid);
fprintf(f, "ANSWER: PASS\n");
ast_log(LOG_DEBUG, "Processing Test ID '%s'\n", testid);
res = ast_safe_sleep(chan, 1000);
if (!res) {
/* Step 1: Send "1" */
ast_log(LOG_DEBUG, "TestServer: 1. Send DTMF 1\n");
res = ast_dtmf_stream(chan, NULL, "1", 0);
fprintf(f, "SEND DTMF 1: %s\n", (res < 0) ? "FAIL" : "PASS");
if (res > 0)
res = 0;
}
if (!res) {
/* Step 2: Wait for "2" */
ast_log(LOG_DEBUG, "TestServer: 2. Wait DTMF 2\n");
res = ast_waitfordigit(chan, 3000);
fprintf(f, "WAIT DTMF 2: %s\n", (res != '2') ? "FAIL" : "PASS");
if (res == '2')
res = 0;
else
res = -1;
}
if (!res) {
/* Step 3: Measure noise */
ast_log(LOG_DEBUG, "TestServer: 3. Measure noise\n");
res = measurenoise(chan, 6000, "TestServer");
fprintf(f, "MEASURENOISE: %s (%d)\n", (res < 0) ? "FAIL" : "PASS", res);
if (res > 0)
res = 0;
}
if (!res) {
/* Step 4: Send "4" */
ast_log(LOG_DEBUG, "TestServer: 4. Send DTMF 4\n");
res = ast_dtmf_stream(chan, NULL, "4", 0);
fprintf(f, "SEND DTMF 4: %s\n", (res < 0) ? "FAIL" : "PASS");
if (res > 0)
res = 0;
}
if (!res) {
/* Step 5: Wait one second */
ast_log(LOG_DEBUG, "TestServer: 5. Wait one second\n");
res = ast_safe_sleep(chan, 1000);
fprintf(f, "WAIT 1 SEC: %s\n", (res < 0) ? "FAIL" : "PASS");
if (res > 0)
res = 0;
}
if (!res) {
/* Step 6: Measure noise */
ast_log(LOG_DEBUG, "TestServer: 6. Measure tone\n");
res = measurenoise(chan, 4000, "TestServer");
fprintf(f, "MEASURETONE: %s (%d)\n", (res < 0) ? "FAIL" : "PASS", res);
if (res > 0)
res = 0;
}
if (!res) {
/* Step 7: Send "5" */
ast_log(LOG_DEBUG, "TestServer: 7. Send DTMF 5\n");
res = ast_dtmf_stream(chan, NULL, "5", 0);
fprintf(f, "SEND DTMF 5: %s\n", (res < 0) ? "FAIL" : "PASS");
if (res > 0)
res = 0;
}
if (!res) {
/* Step 8: Transmit tone noise */
ast_log(LOG_DEBUG, "TestServer: 8. Transmit tone\n");
res = sendnoise(chan, 6000);
fprintf(f, "SENDTONE: %s\n", (res < 0) ? "FAIL" : "PASS");
}
if (!res || (res == '7')) {
/* Step 9: Wait for "7" */
ast_log(LOG_DEBUG, "TestServer: 9. Wait DTMF 7\n");
if (!res)
res = ast_waitfordigit(chan, 3000);
fprintf(f, "WAIT DTMF 7: %s\n", (res != '7') ? "FAIL" : "PASS");
if (res == '7')
res = 0;
else
res = -1;
}
if (!res)
res = ast_safe_sleep(chan, 1000);
if (!res) {
/* Step 10: Send "8" */
ast_log(LOG_DEBUG, "TestServer: 10. Send DTMF 8\n");
res = ast_dtmf_stream(chan, NULL, "8", 0);
fprintf(f, "SEND DTMF 8: %s\n", (res < 0) ? "FAIL" : "PASS");
if (res > 0)
res = 0;
}
if (!res) {
/* Step 11: Wait for hangup to arrive! */
ast_log(LOG_DEBUG, "TestServer: 11. Waiting for hangup\n");
res = ast_safe_sleep(chan, 10000);
fprintf(f, "WAIT HANGUP: %s\n", (res < 0) ? "PASS" : "FAIL");
}
ast_log(LOG_DEBUG, "-- TEST COMPLETE--\n");
fprintf(f, "-- END TEST--\n");
fclose(f);
res = -1;
} else
res = -1;
} else {
ast_log(LOG_NOTICE, "Did not read a test ID on '%s'\n", chan->name);
res = -1;
}
LOCAL_USER_REMOVE(u);
return res;
}
int unload_module(void)
{
STANDARD_HANGUP_LOCALUSERS;
ast_unregister_application(testc_app);
return ast_unregister_application(tests_app);
}
int load_module(void)
{
ast_register_application(testc_app, testclient_exec, testc_synopsis, testc_descrip);
return ast_register_application(tests_app, testserver_exec, tests_synopsis, tests_descrip);
}
char *description(void)
{
return tdesc;
}
int usecount(void)
{
int res;
STANDARD_USECOUNT(res);
return res;
}
char *key(void)
{
return ASTERISK_GPL_KEY;
}

View File

@@ -1,91 +0,0 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* Transfer a caller
*
* Copyright (C) 1999, Mark Spencer
*
* Mark Spencer <markster@linux-support.net>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*/
#include <asterisk/lock.h>
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <asterisk/pbx.h>
#include <asterisk/module.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
static char *tdesc = "Transfer";
static char *app = "Transfer";
static char *synopsis = "Transfer caller to remote extension";
static char *descrip =
" Transfer(exten): Requests the remote caller be transferred to\n"
"a given extension. Returns -1 on hangup, or 0 on completion\n"
"regardless of whether the transfer was successful. If the transfer\n"
"was *not* supported or successful and there exists a priority n + 101,\n"
"then that priority will be taken next.\n" ;
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
static int transfer_exec(struct ast_channel *chan, void *data)
{
int res=0;
struct localuser *u;
if (!data || !strlen(data)) {
ast_log(LOG_WARNING, "Transfer requires an argument (destination)\n");
res = 1;
}
LOCAL_USER_ADD(u);
if (!res) {
res = ast_transfer(chan, data);
}
if (!res) {
/* Look for a "busy" place */
if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 101, chan->callerid))
chan->priority += 100;
}
if (res > 0)
res = 0;
LOCAL_USER_REMOVE(u);
return res;
}
int unload_module(void)
{
STANDARD_HANGUP_LOCALUSERS;
return ast_unregister_application(app);
}
int load_module(void)
{
return ast_register_application(app, transfer_exec, synopsis, descrip);
}
char *description(void)
{
return tdesc;
}
int usecount(void)
{
int res;
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -1,145 +0,0 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* Caller*id name lookup - Look up the caller's name via DNS
*
* Copyright (C) 1999-2004, Digium
*
* Mark Spencer <markster@linux-support.net>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*/
#include <asterisk/lock.h>
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <asterisk/pbx.h>
#include <asterisk/options.h>
#include <asterisk/config.h>
#include <asterisk/module.h>
#include <asterisk/enum.h>
#include <asterisk/utils.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
static char *tdesc = "TXTCIDName";
static char *app = "TXTCIDName";
static char *synopsis = "Lookup caller name from TXT record";
static char *descrip =
" TXTLookup(CallerID): Looks up a Caller Name via DNS and sets\n"
"the variable 'TXTCIDNAME'. TXTCIDName will either be blank\n"
"or return the value found in the TXT record in DNS.\n" ;
#define ENUM_CONFIG "enum.conf"
static char h323driver[80] = "";
#define H323DRIVERDEFAULT "H323"
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
static int txtcidname_exec(struct ast_channel *chan, void *data)
{
int res=0;
char tech[80];
char txt[256] = "";
char dest[80];
struct localuser *u;
if (!data || !strlen(data)) {
ast_log(LOG_WARNING, "TXTCIDName requires an argument (extension)\n");
res = 1;
}
LOCAL_USER_ADD(u);
if (!res) {
res = ast_get_txt(chan, data, dest, sizeof(dest), tech, sizeof(tech), txt, sizeof(txt));
}
LOCAL_USER_REMOVE(u);
/* Parse it out */
if (res > 0) {
if (!ast_strlen_zero(txt)) {
pbx_builtin_setvar_helper(chan, "TXTCIDNAME", txt);
#if 0
ast_log(LOG_DEBUG, "TXTCIDNAME got '%s'\n", txt);
#endif
}
}
if (!res) {
/* Look for a "busy" place */
if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 101, chan->callerid))
chan->priority += 100;
} else if (res > 0)
res = 0;
return res;
}
static int load_config(void)
{
struct ast_config *cfg;
char *s;
cfg = ast_load(ENUM_CONFIG);
if (cfg) {
if (!(s=ast_variable_retrieve(cfg, "general", "h323driver"))) {
strncpy(h323driver, H323DRIVERDEFAULT, sizeof(h323driver) - 1);
} else {
strncpy(h323driver, s, sizeof(h323driver) - 1);
}
ast_destroy(cfg);
return 0;
}
ast_log(LOG_NOTICE, "No ENUM Config file, using defaults\n");
return 0;
}
int unload_module(void)
{
STANDARD_HANGUP_LOCALUSERS;
return ast_unregister_application(app);
}
int load_module(void)
{
int res;
res = ast_register_application(app, txtcidname_exec, synopsis, descrip);
if (res)
return(res);
if ((res=load_config())) {
return(res);
}
return(0);
}
int reload(void)
{
return(load_config());
}
char *description(void)
{
return tdesc;
}
int usecount(void)
{
int res;
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -1,139 +0,0 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* App to transmit a URL
*
* Copyright (C) 1999, Mark Spencer
*
* Mark Spencer <markster@linux-support.net>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*/
#include <asterisk/lock.h>
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <asterisk/pbx.h>
#include <asterisk/module.h>
#include <asterisk/translate.h>
#include <asterisk/image.h>
#include <string.h>
#include <stdlib.h>
static char *tdesc = "Send URL Applications";
static char *app = "SendURL";
static char *synopsis = "Send a URL";
static char *descrip =
" SendURL(URL[|option]): Requests client go to URL. If the client\n"
"does not support html transport, and there exists a step with\n"
"priority n + 101, then execution will continue at that step.\n"
"Otherwise, execution will continue at the next priority level.\n"
"SendURL only returns 0 if the URL was sent correctly or if\n"
"the channel does not support HTML transport, and -1 otherwise.\n"
"If the option 'wait' is specified, execution will wait for an\n"
"acknowledgement that the URL has been loaded before continuing\n"
"and will return -1 if the peer is unable to load the URL\n";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
static int sendurl_exec(struct ast_channel *chan, void *data)
{
int res = 0;
struct localuser *u;
char tmp[256];
char *options;
int option_wait=0;
struct ast_frame *f;
char *stringp=NULL;
if (!data || !strlen((char *)data)) {
ast_log(LOG_WARNING, "SendURL requires an argument (URL)\n");
return -1;
}
strncpy(tmp, (char *)data, sizeof(tmp)-1);
stringp=tmp;
strsep(&stringp, "|");
options = strsep(&stringp, "|");
if (options && !strcasecmp(options, "wait"))
option_wait = 1;
LOCAL_USER_ADD(u);
if (!ast_channel_supports_html(chan)) {
/* Does not support transport */
if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 101, chan->callerid))
chan->priority += 100;
LOCAL_USER_REMOVE(u);
return 0;
}
res = ast_channel_sendurl(chan, tmp);
if (res > -1) {
if (option_wait) {
for(;;) {
/* Wait for an event */
res = ast_waitfor(chan, -1);
if (res < 0)
break;
f = ast_read(chan);
if (!f) {
res = -1;
break;
}
if (f->frametype == AST_FRAME_HTML) {
switch(f->subclass) {
case AST_HTML_LDCOMPLETE:
res = 0;
ast_frfree(f);
goto out;
break;
case AST_HTML_NOSUPPORT:
/* Does not support transport */
if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 101, chan->callerid))
chan->priority += 100;
res = 0;
goto out;
break;
default:
ast_log(LOG_WARNING, "Don't know what to do with HTML subclass %d\n", f->subclass);
};
}
ast_frfree(f);
}
}
}
out:
LOCAL_USER_REMOVE(u);
return res;
}
int unload_module(void)
{
STANDARD_HANGUP_LOCALUSERS;
return ast_unregister_application(app);
}
int load_module(void)
{
return ast_register_application(app, sendurl_exec, synopsis, descrip);
}
char *description(void)
{
return tdesc;
}
int usecount(void)
{
int res;
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -1,106 +0,0 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* UserEvent application -- send manager event
*
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*/
#include <asterisk/lock.h>
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <asterisk/pbx.h>
#include <asterisk/module.h>
#include <asterisk/manager.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
static char *tdesc = "Custom User Event Application";
static char *app = "UserEvent";
static char *synopsis = "Send an arbitrary event to the manager interface";
static char *descrip =
" UserEvent(eventname[|body]): Sends an arbitrary event to the\n"
"manager interface, with an optional body representing additional\n"
"arguments. The format of the event will be:\n"
" Event: UserEvent<specified event name>\n"
" Channel: <channel name>\n"
" Uniqueid: <call uniqueid>\n"
" [body]\n"
"If the body is not specified, only Event, Channel, and Uniqueid fields\n"
"will be present. Returns 0.";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
static int userevent_exec(struct ast_channel *chan, void *data)
{
struct localuser *u;
char info[512];
char eventname[512];
char *eventbody;
if (!data || !strlen(data)) {
ast_log(LOG_WARNING, "UserEvent requires an argument (eventname|optional event body)\n");
return -1;
}
strncpy(info, (char *)data, strlen((char *)data) + AST_MAX_EXTENSION-1);
snprintf(eventname, sizeof(eventname), "UserEvent%s", info);
eventbody = strchr(eventname, '|');
if (eventbody) {
*eventbody = '\0';
eventbody++;
}
LOCAL_USER_ADD(u);
if(eventbody) {
ast_log(LOG_DEBUG, "Sending user event: %s, %s\n", eventname, eventbody);
manager_event(EVENT_FLAG_CALL, eventname,
"Channel: %s\r\nUniqueid: %s\r\n%s\r\n",
chan->name, chan->uniqueid, eventbody);
} else {
ast_log(LOG_DEBUG, "Sending user event: %s\n", eventname);
manager_event(EVENT_FLAG_CALL, eventname,
"Channel: %s\r\nUniqueid: %s\r\n", chan->name, chan->uniqueid);
}
LOCAL_USER_REMOVE(u);
return 0;
}
int unload_module(void)
{
STANDARD_HANGUP_LOCALUSERS;
return ast_unregister_application(app);
}
int load_module(void)
{
return ast_register_application(app, userevent_exec, synopsis, descrip);
}
char *description(void)
{
return tdesc;
}
int usecount(void)
{
int res;
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -1,110 +0,0 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* Verbose application
*
* Copyright (c) 2004 Tilghman Lesher. All rights reserved.
*
* Tilghman Lesher <app_verbose_v001@the-tilghman.com>
*
* This code is released by the author with no restrictions on usage.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <asterisk/options.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <asterisk/pbx.h>
#include <asterisk/module.h>
static char *tdesc = "Send verbose output";
static char *app_verbose = "Verbose";
static char *verbose_synopsis = "Send arbitrary text to verbose output";
static char *verbose_descrip =
"Verbose([<level>|]<message>)\n"
" level must be an integer value. If not specified, defaults to 0."
" Always returns 0.\n";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
static int verbose_exec(struct ast_channel *chan, void *data)
{
char *vtext;
int vsize;
if (data) {
vtext = ast_strdupa((char *)data);
if (vtext) {
char *tmp = strsep(&vtext, "|,");
if (vtext) {
if (sscanf(tmp, "%d", &vsize) != 1) {
vsize = 0;
ast_log(LOG_WARNING, "'%s' is not a verboser number\n", vtext);
}
} else {
vtext = tmp;
vsize = 0;
}
if (option_verbose >= vsize) {
switch (vsize) {
case 0:
ast_verbose("%s\n", vtext);
break;
case 1:
ast_verbose(VERBOSE_PREFIX_1 "%s\n", vtext);
break;
case 2:
ast_verbose(VERBOSE_PREFIX_2 "%s\n", vtext);
break;
case 3:
ast_verbose(VERBOSE_PREFIX_3 "%s\n", vtext);
break;
default:
ast_verbose(VERBOSE_PREFIX_4 "%s\n", vtext);
}
}
} else {
ast_log(LOG_ERROR, "Out of memory\n");
}
}
return 0;
}
int unload_module(void)
{
STANDARD_HANGUP_LOCALUSERS;
return ast_unregister_application(app_verbose);
}
int load_module(void)
{
return ast_register_application(app_verbose, verbose_exec, verbose_synopsis, verbose_descrip);
}
char *description(void)
{
return tdesc;
}
int usecount(void)
{
int res;
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,129 +0,0 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* Wait for Ring Application
*
* Copyright (C) 2003, Digium
*
* Mark Spencer <markster@linux-support.net>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*/
#include <sys/types.h>
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <asterisk/pbx.h>
#include <asterisk/module.h>
#include <asterisk/options.h>
#include <asterisk/lock.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
static char *synopsis = "Wait for Ring Application";
static char *tdesc = "Waits until first ring after time";
static char *desc = " WaitForRing(timeout)\n"
"Returns 0 after waiting at least timeout seconds. and\n"
"only after the next ring has completed. Returns 0 on\n"
"success or -1 on hangup\n";
static char *app = "WaitForRing";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
static int waitforring_exec(struct ast_channel *chan, void *data)
{
struct localuser *u;
struct ast_frame *f;
int res = 0;
int ms;
if (!data || (sscanf(data, "%d", &ms) != 1)) {
ast_log(LOG_WARNING, "WaitForRing requires an argument (minimum seconds)\n");
return 0;
}
ms *= 1000;
LOCAL_USER_ADD(u);
while(ms > 0) {
ms = ast_waitfor(chan, ms);
if (ms < 0) {
res = ms;
break;
}
if (ms > 0) {
f = ast_read(chan);
if (!f) {
res = -1;
break;
}
if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_RING)) {
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "Got a ring but still waiting for timeout\n");
}
ast_frfree(f);
}
}
/* Now we're really ready for the ring */
if (!res) {
ms = 99999999;
while(ms > 0) {
ms = ast_waitfor(chan, ms);
if (ms < 0) {
res = ms;
break;
}
if (ms > 0) {
f = ast_read(chan);
if (!f) {
res = -1;
break;
}
if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_RING)) {
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "Got a ring after the timeout\n");
ast_frfree(f);
break;
}
ast_frfree(f);
}
}
}
LOCAL_USER_REMOVE(u);
return res;
}
int unload_module(void)
{
STANDARD_HANGUP_LOCALUSERS;
return ast_unregister_application(app);
}
int load_module(void)
{
return ast_register_application(app, waitforring_exec, synopsis, desc);
}
char *description(void)
{
return tdesc;
}
int usecount(void)
{
int res;
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -1,115 +0,0 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* Playback the special information tone to get rid of telemarketers
*
* Copyright (C) 1999, Mark Spencer
*
* Mark Spencer <markster@linux-support.net>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*/
#include <asterisk/lock.h>
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <asterisk/pbx.h>
#include <asterisk/module.h>
#include <asterisk/translate.h>
#include <string.h>
#include <stdlib.h>
static char *tdesc = "Block Telemarketers with Special Information Tone";
static char *app = "Zapateller";
static char *synopsis = "Block telemarketers with SIT";
static char *descrip =
" Zapateller(options): Generates special information tone to block\n"
"telemarketers from calling you. Returns 0 normally or -1 on hangup.\n"
"Options is a pipe-delimited list of options. The following options\n"
"are available: 'answer' causes the line to be answered before playing\n"
"the tone, 'nocallerid' causes Zapateller to only play the tone if there\n"
"is no callerid information available. Options should be separated by |\n"
"characters\n";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
static int zapateller_exec(struct ast_channel *chan, void *data)
{
int res = 0;
struct localuser *u;
int answer = 0, nocallerid = 0;
char *c;
char *stringp=NULL;
LOCAL_USER_ADD(u);
stringp=data;
c = strsep(&stringp, "|");
while(c && strlen(c)) {
if (!strcasecmp(c, "answer"))
answer = 1;
else if (!strcasecmp(c, "nocallerid"))
nocallerid = 1;
c = strsep(&stringp, "|");
}
ast_stopstream(chan);
if (chan->_state != AST_STATE_UP) {
if (answer)
res = ast_answer(chan);
if (!res) {
res = ast_safe_sleep(chan, 500);
}
}
if (chan->callerid && nocallerid) {
LOCAL_USER_REMOVE(u);
return res;
}
if (!res)
res = ast_tonepair(chan, 950, 0, 330, 0);
if (!res)
res = ast_tonepair(chan, 1400, 0, 330, 0);
if (!res)
res = ast_tonepair(chan, 1800, 0, 330, 0);
if (!res)
res = ast_tonepair(chan, 0, 0, 1000, 0);
LOCAL_USER_REMOVE(u);
return res;
}
int unload_module(void)
{
STANDARD_HANGUP_LOCALUSERS;
return ast_unregister_application(app);
}
int load_module(void)
{
return ast_register_application(app, zapateller_exec, synopsis, descrip);
}
char *description(void)
{
return tdesc;
}
int usecount(void)
{
int res;
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -1,310 +0,0 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* Zap Barge support
*
* Copyright (C) 2003, Digium
*
* Mark Spencer <markster@digium.com>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*
* Special thanks to comphealth.com for sponsoring this
* GPL application.
*/
#include <asterisk/lock.h>
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <asterisk/pbx.h>
#include <asterisk/module.h>
#include <asterisk/config.h>
#include <asterisk/app.h>
#include <asterisk/options.h>
#include <asterisk/cli.h>
#include <asterisk/say.h>
#include <asterisk/utils.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#ifdef __linux__
#include <linux/zaptel.h>
#else
#include <zaptel.h>
#endif /* __linux__ */
static char *tdesc = "Barge in on Zap channel application";
static char *app = "ZapBarge";
static char *synopsis = "Barge in (monitor) Zap channel";
static char *descrip =
" ZapBarge([channel]): Barges in on a specified zap\n"
"channel or prompts if one is not specified. Returns\n"
"-1 when caller user hangs up and is independent of the\n"
"state of the channel being monitored.";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
#define CONF_SIZE 160
static int careful_write(int fd, unsigned char *data, int len)
{
int res;
while(len) {
res = write(fd, data, len);
if (res < 1) {
if (errno != EAGAIN) {
ast_log(LOG_WARNING, "Failed to write audio data to conference: %s\n", strerror(errno));
return -1;
} else
return 0;
}
len -= res;
data += res;
}
return 0;
}
static int conf_run(struct ast_channel *chan, int confno, int confflags)
{
int fd;
struct zt_confinfo ztc;
struct ast_frame *f;
struct ast_channel *c;
struct ast_frame fr;
int outfd;
int ms;
int nfds;
int res;
int flags;
int retryzap;
int origfd;
int ret = -1;
ZT_BUFFERINFO bi;
char __buf[CONF_SIZE + AST_FRIENDLY_OFFSET];
char *buf = __buf + AST_FRIENDLY_OFFSET;
/* Set it into U-law mode (write) */
if (ast_set_write_format(chan, AST_FORMAT_ULAW) < 0) {
ast_log(LOG_WARNING, "Unable to set '%s' to write ulaw mode\n", chan->name);
goto outrun;
}
/* Set it into U-law mode (read) */
if (ast_set_read_format(chan, AST_FORMAT_ULAW) < 0) {
ast_log(LOG_WARNING, "Unable to set '%s' to read ulaw mode\n", chan->name);
goto outrun;
}
ast_indicate(chan, -1);
retryzap = strcasecmp(chan->type, "Zap");
zapretry:
origfd = chan->fds[0];
if (retryzap) {
fd = open("/dev/zap/pseudo", O_RDWR);
if (fd < 0) {
ast_log(LOG_WARNING, "Unable to open pseudo channel: %s\n", strerror(errno));
goto outrun;
}
/* Make non-blocking */
flags = fcntl(fd, F_GETFL);
if (flags < 0) {
ast_log(LOG_WARNING, "Unable to get flags: %s\n", strerror(errno));
close(fd);
goto outrun;
}
if (fcntl(fd, F_SETFL, flags | O_NONBLOCK)) {
ast_log(LOG_WARNING, "Unable to set flags: %s\n", strerror(errno));
close(fd);
goto outrun;
}
/* Setup buffering information */
memset(&bi, 0, sizeof(bi));
bi.bufsize = CONF_SIZE;
bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
bi.numbufs = 4;
if (ioctl(fd, ZT_SET_BUFINFO, &bi)) {
ast_log(LOG_WARNING, "Unable to set buffering information: %s\n", strerror(errno));
close(fd);
goto outrun;
}
nfds = 1;
} else {
/* XXX Make sure we're not running on a pseudo channel XXX */
fd = chan->fds[0];
nfds = 0;
}
memset(&ztc, 0, sizeof(ztc));
/* Check to see if we're in a conference... */
ztc.chan = 0;
if (ioctl(fd, ZT_GETCONF, &ztc)) {
ast_log(LOG_WARNING, "Error getting conference\n");
close(fd);
goto outrun;
}
if (ztc.confmode) {
/* Whoa, already in a conference... Retry... */
if (!retryzap) {
ast_log(LOG_DEBUG, "Zap channel is in a conference already, retrying with pseudo\n");
retryzap = 1;
goto zapretry;
}
}
memset(&ztc, 0, sizeof(ztc));
/* Add us to the conference */
ztc.chan = 0;
ztc.confno = confno;
ztc.confmode = ZT_CONF_MONITORBOTH;
if (ioctl(fd, ZT_SETCONF, &ztc)) {
ast_log(LOG_WARNING, "Error setting conference\n");
close(fd);
goto outrun;
}
ast_log(LOG_DEBUG, "Placed channel %s in ZAP channel %d monitor\n", chan->name, confno);
for(;;) {
outfd = -1;
ms = -1;
c = ast_waitfor_nandfds(&chan, 1, &fd, nfds, NULL, &outfd, &ms);
if (c) {
if (c->fds[0] != origfd) {
if (retryzap) {
/* Kill old pseudo */
close(fd);
}
ast_log(LOG_DEBUG, "Ooh, something swapped out under us, starting over\n");
retryzap = 0;
goto zapretry;
}
f = ast_read(c);
if (!f)
break;
if ((f->frametype == AST_FRAME_DTMF) && (f->subclass == '#')) {
ret = 0;
break;
} else if (fd != chan->fds[0]) {
if (f->frametype == AST_FRAME_VOICE) {
if (f->subclass == AST_FORMAT_ULAW) {
/* Carefully write */
careful_write(fd, f->data, f->datalen);
} else
ast_log(LOG_WARNING, "Huh? Got a non-ulaw (%d) frame in the conference\n", f->subclass);
}
}
ast_frfree(f);
} else if (outfd > -1) {
res = read(outfd, buf, CONF_SIZE);
if (res > 0) {
memset(&fr, 0, sizeof(fr));
fr.frametype = AST_FRAME_VOICE;
fr.subclass = AST_FORMAT_ULAW;
fr.datalen = res;
fr.samples = res;
fr.data = buf;
fr.offset = AST_FRIENDLY_OFFSET;
if (ast_write(chan, &fr) < 0) {
ast_log(LOG_WARNING, "Unable to write frame to channel: %s\n", strerror(errno));
/* break; */
}
} else
ast_log(LOG_WARNING, "Failed to read frame: %s\n", strerror(errno));
}
}
if (fd != chan->fds[0])
close(fd);
else {
/* Take out of conference */
/* Add us to the conference */
ztc.chan = 0;
ztc.confno = 0;
ztc.confmode = 0;
if (ioctl(fd, ZT_SETCONF, &ztc)) {
ast_log(LOG_WARNING, "Error setting conference\n");
}
}
outrun:
return ret;
}
static int conf_exec(struct ast_channel *chan, void *data)
{
int res=-1;
struct localuser *u;
int retrycnt = 0;
int confflags = 0;
int confno = 0;
char confstr[80] = "";
if (data && !ast_strlen_zero(data)) {
if ((sscanf(data, "Zap/%d", &confno) != 1) &&
(sscanf(data, "%d", &confno) != 1)) {
ast_log(LOG_WARNING, "ZapBarge Argument (if specified) must be a channel number, not '%s'\n", (char *)data);
return 0;
}
}
LOCAL_USER_ADD(u);
if (chan->_state != AST_STATE_UP)
ast_answer(chan);
while(!confno && (++retrycnt < 4)) {
/* Prompt user for conference number */
confstr[0] = '\0';
res = ast_app_getdata(chan, "conf-getchannel",confstr, sizeof(confstr) - 1, 0);
if (res <0) goto out;
if (sscanf(confstr, "%d", &confno) != 1)
confno = 0;
}
if (confno) {
/* XXX Should prompt user for pin if pin is required XXX */
/* Run the conference */
res = conf_run(chan, confno, confflags);
}
out:
/* Do the conference */
LOCAL_USER_REMOVE(u);
return res;
}
int unload_module(void)
{
STANDARD_HANGUP_LOCALUSERS;
return ast_unregister_application(app);
}
int load_module(void)
{
return ast_register_application(app, conf_exec, synopsis, descrip);
}
char *description(void)
{
return tdesc;
}
int usecount(void)
{
int res;
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -1,249 +0,0 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* Execute an ISDN RAS
*
* Copyright (C) 1999, Mark Spencer
*
* Mark Spencer <markster@linux-support.net>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*/
#include <asterisk/lock.h>
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <asterisk/pbx.h>
#include <asterisk/module.h>
#include <asterisk/options.h>
#include <sys/ioctl.h>
#include <sys/wait.h>
#ifdef __linux__
#include <sys/signal.h>
#else
#include <signal.h>
#endif /* __linux__ */
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
#include <fcntl.h>
/* Need some zaptel help here */
#ifdef __linux__
#include <linux/zaptel.h>
#else
#include <zaptel.h>
#endif /* __linux__ */
static char *tdesc = "Zap RAS Application";
static char *app = "ZapRAS";
static char *synopsis = "Executes Zaptel ISDN RAS application";
static char *descrip =
" ZapRAS(args): Executes a RAS server using pppd on the given channel.\n"
"The channel must be a clear channel (i.e. PRI source) and a Zaptel\n"
"channel to be able to use this function (No modem emulation is included).\n"
"Your pppd must be patched to be zaptel aware. Arguments should be\n"
"separated by | characters. Always returns -1.\n";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
#define PPP_MAX_ARGS 32
#define PPP_EXEC "/usr/sbin/pppd"
static pid_t spawn_ras(struct ast_channel *chan, char *args)
{
pid_t pid;
int x;
char *c;
char *argv[PPP_MAX_ARGS];
int argc = 0;
char *stringp=NULL;
/* Start by forking */
pid = fork();
if (pid)
return pid;
/* Execute RAS on File handles */
dup2(chan->fds[0], STDIN_FILENO);
/* Close other file descriptors */
for (x=STDERR_FILENO + 1;x<1024;x++)
close(x);
/* Restore original signal handlers */
for (x=0;x<NSIG;x++)
signal(x, SIG_DFL);
/* Reset all arguments */
memset(argv, 0, sizeof(argv));
/* First argument is executable, followed by standard
arguments for zaptel PPP */
argv[argc++] = PPP_EXEC;
argv[argc++] = "nodetach";
/* And all the other arguments */
stringp=args;
c = strsep(&stringp, "|");
while(c && strlen(c) && (argc < (PPP_MAX_ARGS - 4))) {
argv[argc++] = c;
c = strsep(&stringp, "|");
}
argv[argc++] = "plugin";
argv[argc++] = "zaptel.so";
argv[argc++] = "stdin";
#if 0
for (x=0;x<argc;x++) {
fprintf(stderr, "Arg %d: %s\n", x, argv[x]);
}
#endif
/* Finally launch PPP */
execv(PPP_EXEC, argv);
fprintf(stderr, "Failed to exec PPPD!\n");
exit(1);
}
static void run_ras(struct ast_channel *chan, char *args)
{
pid_t pid;
int status;
int res;
int signalled = 0;
struct zt_bufferinfo bi;
int x;
pid = spawn_ras(chan, args);
if (pid < 0) {
ast_log(LOG_WARNING, "Failed to spawn RAS\n");
} else {
for (;;) {
res = wait4(pid, &status, WNOHANG, NULL);
if (!res) {
/* Check for hangup */
if (chan->_softhangup && !signalled) {
ast_log(LOG_DEBUG, "Channel '%s' hungup. Signalling RAS at %d to die...\n", chan->name, pid);
kill(pid, SIGTERM);
signalled=1;
}
/* Try again */
sleep(1);
continue;
}
if (res < 0) {
ast_log(LOG_WARNING, "wait4 returned %d: %s\n", res, strerror(errno));
}
if (option_verbose > 2) {
if (WIFEXITED(status)) {
ast_verbose(VERBOSE_PREFIX_3 "RAS on %s terminated with status %d\n", chan->name, WEXITSTATUS(status));
} else if (WIFSIGNALED(status)) {
ast_verbose(VERBOSE_PREFIX_3 "RAS on %s terminated with signal %d\n",
chan->name, WTERMSIG(status));
} else {
ast_verbose(VERBOSE_PREFIX_3 "RAS on %s terminated weirdly.\n", chan->name);
}
}
/* Throw back into audio mode */
x = 1;
ioctl(chan->fds[0], ZT_AUDIOMODE, &x);
/* Double check buffering too */
res = ioctl(chan->fds[0], ZT_GET_BUFINFO, &bi);
if (!res) {
/* XXX This is ZAP_BLOCKSIZE XXX */
bi.bufsize = 204;
bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
bi.numbufs = 4;
res = ioctl(chan->fds[0], ZT_SET_BUFINFO, &bi);
if (res < 0) {
ast_log(LOG_WARNING, "Unable to set buffer policy on channel %s\n", chan->name);
}
} else
ast_log(LOG_WARNING, "Unable to check buffer policy on channel %s\n", chan->name);
break;
}
}
}
static int zapras_exec(struct ast_channel *chan, void *data)
{
int res=-1;
char args[256];
struct localuser *u;
ZT_PARAMS ztp;
if (!data)
data = "";
LOCAL_USER_ADD(u);
strncpy(args, data, sizeof(args) - 1);
/* Answer the channel if it's not up */
if (chan->_state != AST_STATE_UP)
ast_answer(chan);
if (strcasecmp(chan->type, "Zap")) {
/* If it's not a zap channel, we're done. Wait a couple of
seconds and then hangup... */
if (option_verbose > 1)
ast_verbose(VERBOSE_PREFIX_2 "Channel %s is not a Zap channel\n", chan->name);
sleep(2);
} else {
memset(&ztp, 0, sizeof(ztp));
if (ioctl(chan->fds[0], ZT_GET_PARAMS, &ztp)) {
ast_log(LOG_WARNING, "Unable to get zaptel parameters\n");
} else if (ztp.sigtype != ZT_SIG_CLEAR) {
if (option_verbose > 1)
ast_verbose(VERBOSE_PREFIX_2 "Channel %s is not a clear channel\n", chan->name);
} else {
/* Everything should be okay. Run PPP. */
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "Starting RAS on %s\n", chan->name);
/* Execute RAS */
run_ras(chan, args);
}
}
LOCAL_USER_REMOVE(u);
return res;
}
int unload_module(void)
{
STANDARD_HANGUP_LOCALUSERS;
return ast_unregister_application(app);
}
int load_module(void)
{
return ast_register_application(app, zapras_exec, synopsis, descrip);
}
char *description(void)
{
return tdesc;
}
int usecount(void)
{
int res;
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -1,368 +0,0 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* Zap Scanner
*
* Copyright (C) 2003, Digium
*
* Modified from app_zapbarge by David Troy <dave@toad.net>
*
* Mark Spencer <markster@digium.com>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*
* Special thanks to comphealth.com for sponsoring this
* GPL application.
*/
#include <asterisk/lock.h>
#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <asterisk/pbx.h>
#include <asterisk/module.h>
#include <asterisk/config.h>
#include <asterisk/app.h>
#include <asterisk/options.h>
#include <asterisk/cli.h>
#include <asterisk/say.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#ifdef __linux__
#include <linux/zaptel.h>
#else
#include <zaptel.h>
#endif /* __linux__ */
static char *tdesc = "Scan Zap channels application";
static char *app = "ZapScan";
static char *synopsis = "Scan Zap channels to monitor calls";
static char *descrip =
" ZapScan allows a call center manager to monitor Zap channels in\n"
"a convenient way. Use '#' to select the next channel and use '*' to exit\n";
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
#define CONF_SIZE 160
static struct ast_channel *get_zap_channel_locked(int num) {
struct ast_channel *c=NULL;
char name[80];
snprintf(name,sizeof(name),"Zap/%d-1",num);
c = ast_channel_walk_locked(NULL);
while(c) {
if (!strcasecmp(c->name, name)) {
break;
}
ast_mutex_unlock(&c->lock);
c = ast_channel_walk_locked(c);
}
return c;
}
static int careful_write(int fd, unsigned char *data, int len)
{
int res;
while(len) {
res = write(fd, data, len);
if (res < 1) {
if (errno != EAGAIN) {
ast_log(LOG_WARNING, "Failed to write audio data to conference: %s\n", strerror(errno));
return -1;
} else
return 0;
}
len -= res;
data += res;
}
return 0;
}
static int conf_run(struct ast_channel *chan, int confno, int confflags)
{
int fd;
struct zt_confinfo ztc;
struct ast_frame *f;
struct ast_channel *c;
struct ast_frame fr;
int outfd;
int ms;
int nfds;
int res;
int flags;
int retryzap;
int origfd;
int ret = -1;
char input[4];
int ic=0;
ZT_BUFFERINFO bi;
char __buf[CONF_SIZE + AST_FRIENDLY_OFFSET];
char *buf = __buf + AST_FRIENDLY_OFFSET;
/* Set it into U-law mode (write) */
if (ast_set_write_format(chan, AST_FORMAT_ULAW) < 0) {
ast_log(LOG_WARNING, "Unable to set '%s' to write ulaw mode\n", chan->name);
goto outrun;
}
/* Set it into U-law mode (read) */
if (ast_set_read_format(chan, AST_FORMAT_ULAW) < 0) {
ast_log(LOG_WARNING, "Unable to set '%s' to read ulaw mode\n", chan->name);
goto outrun;
}
ast_indicate(chan, -1);
retryzap = strcasecmp(chan->type, "Zap");
zapretry:
origfd = chan->fds[0];
if (retryzap) {
fd = open("/dev/zap/pseudo", O_RDWR);
if (fd < 0) {
ast_log(LOG_WARNING, "Unable to open pseudo channel: %s\n", strerror(errno));
goto outrun;
}
/* Make non-blocking */
flags = fcntl(fd, F_GETFL);
if (flags < 0) {
ast_log(LOG_WARNING, "Unable to get flags: %s\n", strerror(errno));
close(fd);
goto outrun;
}
if (fcntl(fd, F_SETFL, flags | O_NONBLOCK)) {
ast_log(LOG_WARNING, "Unable to set flags: %s\n", strerror(errno));
close(fd);
goto outrun;
}
/* Setup buffering information */
memset(&bi, 0, sizeof(bi));
bi.bufsize = CONF_SIZE;
bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
bi.numbufs = 4;
if (ioctl(fd, ZT_SET_BUFINFO, &bi)) {
ast_log(LOG_WARNING, "Unable to set buffering information: %s\n", strerror(errno));
close(fd);
goto outrun;
}
nfds = 1;
} else {
/* XXX Make sure we're not running on a pseudo channel XXX */
fd = chan->fds[0];
nfds = 0;
}
memset(&ztc, 0, sizeof(ztc));
/* Check to see if we're in a conference... */
ztc.chan = 0;
if (ioctl(fd, ZT_GETCONF, &ztc)) {
ast_log(LOG_WARNING, "Error getting conference\n");
close(fd);
goto outrun;
}
if (ztc.confmode) {
/* Whoa, already in a conference... Retry... */
if (!retryzap) {
ast_log(LOG_DEBUG, "Zap channel is in a conference already, retrying with pseudo\n");
retryzap = 1;
goto zapretry;
}
}
memset(&ztc, 0, sizeof(ztc));
/* Add us to the conference */
ztc.chan = 0;
ztc.confno = confno;
ztc.confmode = ZT_CONF_MONITORBOTH;
if (ioctl(fd, ZT_SETCONF, &ztc)) {
ast_log(LOG_WARNING, "Error setting conference\n");
close(fd);
goto outrun;
}
ast_log(LOG_DEBUG, "Placed channel %s in ZAP channel %d monitor\n", chan->name, confno);
for(;;) {
outfd = -1;
ms = -1;
c = ast_waitfor_nandfds(&chan, 1, &fd, nfds, NULL, &outfd, &ms);
if (c) {
if (c->fds[0] != origfd) {
if (retryzap) {
/* Kill old pseudo */
close(fd);
}
ast_log(LOG_DEBUG, "Ooh, something swapped out under us, starting over\n");
retryzap = 0;
goto zapretry;
}
f = ast_read(c);
if (!f)
break;
if(f->frametype == AST_FRAME_DTMF) {
if(f->subclass == '#') {
ret = 0;
break;
}
else if (f->subclass == '*') {
ret = -1;
break;
}
else {
input[ic++] = f->subclass;
}
if(ic == 3) {
input[ic++] = '\0';
ic=0;
ret = atoi(input);
ast_verbose(VERBOSE_PREFIX_3 "Zapscan: change channel to %d\n",ret);
break;
}
}
if (fd != chan->fds[0]) {
if (f->frametype == AST_FRAME_VOICE) {
if (f->subclass == AST_FORMAT_ULAW) {
/* Carefully write */
careful_write(fd, f->data, f->datalen);
} else
ast_log(LOG_WARNING, "Huh? Got a non-ulaw (%d) frame in the conference\n", f->subclass);
}
}
ast_frfree(f);
} else if (outfd > -1) {
res = read(outfd, buf, CONF_SIZE);
if (res > 0) {
memset(&fr, 0, sizeof(fr));
fr.frametype = AST_FRAME_VOICE;
fr.subclass = AST_FORMAT_ULAW;
fr.datalen = res;
fr.samples = res;
fr.data = buf;
fr.offset = AST_FRIENDLY_OFFSET;
if (ast_write(chan, &fr) < 0) {
ast_log(LOG_WARNING, "Unable to write frame to channel: %s\n", strerror(errno));
/* break; */
}
} else
ast_log(LOG_WARNING, "Failed to read frame: %s\n", strerror(errno));
}
}
if (fd != chan->fds[0])
close(fd);
else {
/* Take out of conference */
/* Add us to the conference */
ztc.chan = 0;
ztc.confno = 0;
ztc.confmode = 0;
if (ioctl(fd, ZT_SETCONF, &ztc)) {
ast_log(LOG_WARNING, "Error setting conference\n");
}
}
outrun:
return ret;
}
static int conf_exec(struct ast_channel *chan, void *data)
{
int res=-1;
struct localuser *u;
int confflags = 0;
int confno = 0;
char confstr[80] = "", *tmp;
struct ast_channel *tempchan = NULL, *lastchan = NULL,*ichan = NULL;
struct ast_frame *f;
int input=0;
LOCAL_USER_ADD(u);
if (chan->_state != AST_STATE_UP)
ast_answer(chan);
for (;;) {
if (ast_waitfor(chan, 100) < 0)
break;
f = ast_read(chan);
if (!f)
break;
if ((f->frametype == AST_FRAME_DTMF) && (f->subclass == '*')) {
ast_frfree(f);
break;
}
ast_frfree(f);
ichan = NULL;
if(input) {
ichan = get_zap_channel_locked(input);
input = 0;
}
tempchan = ichan ? ichan : ast_channel_walk_locked(tempchan);
if ( !tempchan && !lastchan )
break;
if ( tempchan && tempchan->type && (!strcmp(tempchan->type, "Zap")) && (tempchan != chan) ) {
ast_verbose(VERBOSE_PREFIX_3 "Zap channel %s is in-use, monitoring...\n", tempchan->name);
strncpy(confstr, tempchan->name, sizeof(confstr) - 1);
ast_mutex_unlock(&tempchan->lock);
if ((tmp = strchr(confstr,'-'))) {
*tmp = '\0';
}
confno = atoi(strchr(confstr,'/') + 1);
ast_stopstream(chan);
ast_say_number(chan, confno, AST_DIGIT_ANY, chan->language, (char *) NULL);
res = conf_run(chan, confno, confflags);
if (res<0) break;
input = res;
} else if (tempchan)
ast_mutex_unlock(&tempchan->lock);
lastchan = tempchan;
}
LOCAL_USER_REMOVE(u);
return res;
}
int unload_module(void)
{
STANDARD_HANGUP_LOCALUSERS;
return ast_unregister_application(app);
}
int load_module(void)
{
return ast_register_application(app, conf_exec, synopsis, descrip);
}
char *description(void)
{
return tdesc;
}
int usecount(void)
{
int res;
STANDARD_USECOUNT(res);
return res;
}
char *key()
{
return ASTERISK_GPL_KEY;
}

View File

@@ -1,287 +0,0 @@
/*
* U-law 8-bit audio data
*
* Source: enter.raw
*
* Copyright (C) 1999, Mark Spencer and Linux Support Services
*
* Distributed under the terms of the GNU General Public License
*
*/
static unsigned char enter[] = {
0xba, 0xba, 0xb0, 0xa6, 0xa9, 0xb8, 0xfe, 0x46, 0x42, 0x46,
0x4a, 0xfe, 0xac, 0xa2, 0x9f, 0x9f, 0xa8, 0xb8, 0x3b, 0x29,
0x35, 0x4a, 0xfe, 0xc1, 0xad, 0xa2, 0xad, 0xc5, 0x4e, 0x68,
0x68, 0xe7, 0xb8, 0xb0, 0xb2, 0xc1, 0xc1, 0xb0, 0xae, 0xcd,
0xfe, 0xfe, 0xcd, 0xcd, 0xfe, 0x68, 0xd3, 0xb2, 0xae, 0xab,
0xb2, 0xfe, 0x35, 0x31, 0xdb, 0xac, 0xab, 0xaf, 0xab, 0xaa,
0xb4, 0x68, 0x3b, 0x39, 0x3f, 0x68, 0xb4, 0xa8, 0xa8, 0xb0,
0xbc, 0xbc, 0xc5, 0x3f, 0x31, 0x37, 0xfe, 0xc1, 0xbc, 0xb0,
0xa5, 0xa2, 0xa8, 0xaf, 0xbe, 0x3b, 0x28, 0x26, 0x3d, 0xbc,
0xb0, 0xae, 0xa2, 0x9f, 0xa2, 0xfe, 0x29, 0x24, 0x29, 0x4a,
0xc5, 0xaa, 0xa8, 0xa9, 0xa8, 0xa5, 0xa7, 0xdb, 0x2c, 0x27,
0x2d, 0x4a, 0xfe, 0xdb, 0xb2, 0xa2, 0x9f, 0x9f, 0xae, 0xe7,
0x2c, 0x22, 0x2b, 0xfe, 0xba, 0xb0, 0xaa, 0x9f, 0xa3, 0xb0,
0x5c, 0x33, 0x33, 0x39, 0x5c, 0xdb, 0xc1, 0xb4, 0xb0, 0xaa,
0xad, 0xba, 0x54, 0x46, 0xfe, 0xe7, 0xfe, 0x54, 0xe7, 0xaf,
0xa6, 0xa7, 0xb0, 0xfe, 0x46, 0x39, 0x5c, 0xe7, 0xdb, 0xfe,
0xba, 0xac, 0xa8, 0xc5, 0x46, 0x33, 0x54, 0xc5, 0xae, 0xad,
0xb2, 0xc1, 0xcd, 0xc1, 0xbc, 0xfe, 0x3f, 0x37, 0xfe, 0xb4,
0xb6, 0xcd, 0xdb, 0xc1, 0xb0, 0xb6, 0xcd, 0x4e, 0x39, 0x37,
0xfe, 0xb0, 0xab, 0xa9, 0xa9, 0xa9, 0xb0, 0x5c, 0x29, 0x25,
0x31, 0xfe, 0xc1, 0xb4, 0xae, 0xab, 0xab, 0xb2, 0xcd, 0x3b,
0x2a, 0x2c, 0x54, 0xb4, 0xb4, 0xba, 0xb2, 0xa3, 0x9f, 0xa8,
0xfe, 0x33, 0x27, 0x2a, 0x39, 0xfe, 0xc1, 0xbe, 0xb0, 0xa2,
0x9f, 0xb0, 0x33, 0x22, 0x25, 0x46, 0xc1, 0xb8, 0xb0, 0xab,
0xa8, 0xa8, 0xb0, 0xbe, 0x42, 0x2c, 0x2e, 0x4a, 0xfe, 0x5c,
0xfe, 0xb4, 0xa8, 0xa8, 0xba, 0xfe, 0x4a, 0x39, 0x39, 0x46,
0xfe, 0xbc, 0xaf, 0xa5, 0xa5, 0xae, 0x68, 0x37, 0x4a, 0xfe,
0xfe, 0x4a, 0x4a, 0xd3, 0xb0, 0xb0, 0xc1, 0x5c, 0x46, 0x46,
0xd3, 0xb6, 0xbe, 0x54, 0x54, 0xc9, 0xab, 0xae, 0xc5, 0x46,
0x4a, 0xfe, 0xcd, 0xc9, 0xcd, 0xe7, 0xe7, 0xc9, 0xb4, 0xc5,
0x4a, 0x2c, 0x37, 0xc1, 0xb0, 0xb2, 0xb4, 0xb2, 0xb6, 0xdb,
0xfe, 0x4a, 0x46, 0x3f, 0x68, 0xba, 0xb2, 0xba, 0xc5, 0xb6,
0xb2, 0xcd, 0x33, 0x2e, 0x39, 0x68, 0xfe, 0xe7, 0xba, 0xaf,
0xa7, 0xa7, 0xad, 0xe7, 0x2d, 0x25, 0x2f, 0xd3, 0xbe, 0xcd,
0xc5, 0xac, 0xa6, 0xac, 0xfe, 0x3b, 0x2c, 0x2d, 0x3d, 0xc1,
0xb4, 0xbe, 0xcd, 0xaf, 0xa5, 0xa8, 0xe7, 0x31, 0x2f, 0x39,
0x46, 0x5c, 0xdb, 0xbc, 0xba, 0xaf, 0xa9, 0xad, 0xfe, 0x2f,
0x2d, 0xba, 0xad, 0xba, 0xfe, 0x3d, 0x42, 0x5c, 0xc9, 0xc1,
0xcd, 0xfe, 0xc1, 0xae, 0xa6, 0xcd, 0x33, 0x25, 0x3b, 0xdb,
0xb0, 0xb6, 0xb8, 0xb6, 0xb4, 0xb8, 0xba, 0xfe, 0x3d, 0x37,
0xfe, 0xba, 0xc1, 0x54, 0x54, 0xd3, 0xb0, 0xb4, 0xe7, 0xfe,
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xd3, 0xb6, 0xa9, 0xa7, 0xba,
0x3d, 0x35, 0xfe, 0xc1, 0xcd, 0x4a, 0x54, 0xbe, 0xb2, 0xb8,
0xfe, 0x46, 0x3b, 0xfe, 0xba, 0xab, 0xc5, 0x46, 0x3b, 0xbc,
0xaa, 0xab, 0xd3, 0x68, 0xfe, 0xd3, 0xcd, 0xdb, 0x54, 0x3d,
0x4a, 0xbc, 0xac, 0xb4, 0x3f, 0x2e, 0x3d, 0xba, 0xb0, 0xb8,
0xba, 0xb6, 0xba, 0xcd, 0xfe, 0xfe, 0x5c, 0x54, 0xc9, 0xb4,
0xbe, 0x54, 0x54, 0xcd, 0xb6, 0xc9, 0x46, 0x54, 0xcd, 0xc5,
0xdb, 0xfe, 0xfe, 0xc1, 0xae, 0xa9, 0xac, 0xfe, 0x35, 0x2e,
0xfe, 0xba, 0xc1, 0x5c, 0xfe, 0xb6, 0xaa, 0xb0, 0xe7, 0x35,
0x2e, 0x39, 0xc1, 0xac, 0xb0, 0xfe, 0xfe, 0xbc, 0xa6, 0xac,
0xc1, 0x42, 0x46, 0x54, 0xfe, 0xfe, 0xfe, 0xfe, 0xc9, 0xae,
0xa9, 0xb0, 0x54, 0x35, 0x37, 0xfe, 0xd3, 0xd3, 0xb8, 0xae,
0xab, 0xb6, 0xe7, 0xfe, 0xfe, 0x68, 0xfe, 0xfe, 0xfe, 0x4e,
0xfe, 0xb0, 0xac, 0xb8, 0xfe, 0xfe, 0xc1, 0xb6, 0xc5, 0x46,
0x3d, 0xe7, 0xb4, 0xa7, 0xab, 0xbc, 0x3f, 0x37, 0x54, 0xba,
0xcd, 0x54, 0x42, 0xc5, 0xae, 0xac, 0xc9, 0x46, 0x3d, 0x54,
0xba, 0xb0, 0xb0, 0xfe, 0x5c, 0xcd, 0xb0, 0xb0, 0xc9, 0x54,
0x54, 0xfe, 0xfe, 0xfe, 0xfe, 0xe7, 0xcd, 0xc1, 0xba, 0xc5,
0xfe, 0x42, 0x46, 0xfe, 0xc5, 0xba, 0xb2, 0xa7, 0xa7, 0xb0,
0xfe, 0x3d, 0x4a, 0x5c, 0xfe, 0xfe, 0xfe, 0xe7, 0xbc, 0xb0,
0xae, 0xc5, 0x4e, 0x39, 0xfe, 0xc5, 0xbe, 0xfe, 0x54, 0xc9,
0xa9, 0xa2, 0xa5, 0xbc, 0x3b, 0x2f, 0x35, 0xfe, 0xc9, 0xfe,
0xfe, 0xc5, 0xa9, 0xa6, 0xb0, 0x54, 0x31, 0x31, 0x3f, 0xd3,
0xbc, 0xc1, 0xcd, 0xb8, 0xae, 0xa8, 0xb4, 0xd3, 0x54, 0x4e,
0x5c, 0x54, 0xfe, 0xdb, 0xba, 0xb4, 0xb4, 0xba, 0xcd, 0x5c,
0x3d, 0x3f, 0x54, 0xfe, 0xcd, 0xaf, 0xa8, 0xac, 0xc5, 0xfe,
0xfe, 0xe7, 0xdb, 0xfe, 0xfe, 0xfe, 0xe7, 0xb8, 0xaf, 0xb0,
0xe7, 0x42, 0x4a, 0xcd, 0xbc, 0xdb, 0x46, 0x68, 0xcd, 0xb0,
0xab, 0xbc, 0xfe, 0x3d, 0x46, 0xfe, 0xb8, 0xbc, 0xd3, 0xd3,
0xb6, 0xb0, 0xb6, 0x5c, 0x3b, 0x35, 0x54, 0xdb, 0xba, 0xb4,
0xc1, 0xc9, 0xc1, 0xba, 0xc9, 0x5c, 0x3d, 0x46, 0xfe, 0xcd,
0xc5, 0xb8, 0xae, 0xaf, 0xb4, 0xd3, 0x54, 0x3d, 0x35, 0x46,
0xfe, 0xdb, 0xbc, 0xb2, 0xa9, 0xab, 0xba, 0x3f, 0x31, 0x39,
0xfe, 0xe7, 0xdb, 0xcd, 0xb8, 0xae, 0xab, 0xac, 0xe7, 0x3d,
0x2d, 0x3f, 0xfe, 0xdb, 0xfe, 0xfe, 0xbc, 0xaa, 0xa8, 0xb0,
0xfe, 0x31, 0x2d, 0x3d, 0xdb, 0xc5, 0xcd, 0xc9, 0xb4, 0xa8,
0xad, 0xc5, 0x46, 0x39, 0x3f, 0x5c, 0xfe, 0xd3, 0xc5, 0xc1,
0xb6, 0xb0, 0xbc, 0x68, 0x46, 0x4e, 0xe7, 0xfe, 0x5c, 0xfe,
0xc1, 0xaf, 0xb0, 0xb8, 0xe7, 0x5c, 0x5c, 0xfe, 0xe7, 0xfe,
0xfe, 0xe7, 0xb0, 0xab, 0xb2, 0x4a, 0x37, 0x3f, 0xcd, 0xbe,
0xc1, 0xe7, 0xe7, 0xd3, 0xb6, 0xb4, 0xc9, 0x3b, 0x33, 0x4a,
0xba, 0xb4, 0xc5, 0xfe, 0xc9, 0xb6, 0xb4, 0xcd, 0xfe, 0x3b,
0x3b, 0xfe, 0xc1, 0xb6, 0xc5, 0xc5, 0xb8, 0xb0, 0xba, 0x4a,
0x31, 0x35, 0x68, 0xcd, 0xc5, 0xba, 0xb4, 0xb0, 0xb0, 0xba,
0x5c, 0x35, 0x2f, 0x4e, 0xd3, 0xc1, 0xdb, 0xd3, 0xb4, 0xa9,
0xab, 0xcd, 0x3b, 0x2f, 0x35, 0xfe, 0xd3, 0xd3, 0xdb, 0xbc,
0xad, 0xa4, 0xb0, 0xfe, 0x2d, 0x2f, 0x3f, 0xe7, 0xe7, 0xe7,
0xcd, 0xb4, 0xaf, 0xad, 0xc5, 0x3d, 0x31, 0x3d, 0xe7, 0xd3,
0xe7, 0xe7, 0xc1, 0xaf, 0xad, 0xb6, 0xfe, 0x4a, 0x42, 0x54,
0xfe, 0x68, 0xfe, 0xd3, 0xb2, 0xae, 0xb4, 0xfe, 0x42, 0x4e,
0xcd, 0xc5, 0xcd, 0xdb, 0xc9, 0xb4, 0xb0, 0xb6, 0xfe, 0x3b,
0x42, 0xe7, 0xb0, 0xb8, 0xcd, 0xfe, 0xc9, 0xb6, 0xb8, 0xfe,
0x42, 0x3d, 0xfe, 0xc1, 0xb0, 0xba, 0xd3, 0xfe, 0xc1, 0xb0,
0xb6, 0xfe, 0x3b, 0x3f, 0xe7, 0xba, 0xb8, 0xbc, 0xc5, 0xc1,
0xc1, 0xcd, 0xfe, 0x3b, 0x37, 0xfe, 0xc1, 0xb4, 0xb6, 0xb8,
0xb6, 0xb8, 0xc5, 0x5c, 0x3f, 0x46, 0xfe, 0xcd, 0xc5, 0xcd,
0xcd, 0xc1, 0xb2, 0xb2, 0xfe, 0x3f, 0x35, 0x54, 0xdb, 0xc1,
0xcd, 0xcd, 0xbc, 0xaf, 0xac, 0xb6, 0x54, 0x35, 0x31, 0x68,
0xba, 0xb8, 0xcd, 0xdb, 0xc9, 0xb2, 0xb4, 0xc9, 0x46, 0x39,
0x42, 0xdb, 0xbc, 0xbc, 0xcd, 0xcd, 0xbe, 0xb2, 0xb8, 0xe7,
0x54, 0x46, 0xfe, 0xfe, 0xdb, 0xc9, 0xc5, 0xbe, 0xbe, 0xc9,
0xfe, 0x5c, 0x5c, 0xfe, 0xd3, 0xcd, 0xcd, 0xc5, 0xb6, 0xb2,
0xc5, 0x68, 0x4e, 0xfe, 0xc5, 0xc1, 0xcd, 0x68, 0x5c, 0xe7,
0xb8, 0xb6, 0xd3, 0x4a, 0x46, 0xfe, 0xbc, 0xb8, 0xc1, 0xe7,
0xe7, 0xc1, 0xb4, 0xbe, 0xfe, 0x3f, 0x3f, 0xfe, 0xba, 0xb2,
0xba, 0xe7, 0xfe, 0xcd, 0xcd, 0xfe, 0x4e, 0x46, 0xfe, 0xc5,
0xb8, 0xb2, 0xba, 0xc1, 0xcd, 0xd3, 0xe7, 0xfe, 0x5c, 0x5c,
0xfe, 0xe7, 0xc5, 0xbe, 0xb6, 0xba, 0xc5, 0xfe, 0x3f, 0x3f,
0x54, 0xfe, 0xd3, 0xc1, 0xbc, 0xb6, 0xb0, 0xb0, 0xd3, 0x54,
0x39, 0x46, 0xfe, 0xc1, 0xcd, 0xe7, 0xe7, 0xc5, 0xb8, 0xb4,
0xd3, 0x54, 0x37, 0x42, 0xdb, 0xbe, 0xc1, 0xd3, 0xcd, 0xb8,
0xb0, 0xb0, 0xcd, 0x4a, 0x3b, 0x42, 0xe7, 0xc5, 0xbe, 0xcd,
0xe7, 0xd3, 0xc5, 0xcd, 0xfe, 0x54, 0x54, 0x68, 0xe7, 0xc5,
0xc1, 0xc1, 0xcd, 0xcd, 0xc9, 0xc9, 0xcd, 0xe7, 0xfe, 0xfe,
0xfe, 0xe7, 0xc5, 0xbe, 0xc1, 0xfe, 0x5c, 0x5c, 0xfe, 0xcd,
0xcd, 0xcd, 0xdb, 0xd3, 0xc1, 0xbc, 0xbe, 0xfe, 0x4e, 0x54,
0xcd, 0xb6, 0xb8, 0xd3, 0x5c, 0x5c, 0xfe, 0xc5, 0xc9, 0xfe,
0x46, 0x4a, 0xe7, 0xb4, 0xb6, 0xc5, 0xfe, 0xe7, 0xcd, 0xc9,
0xdb, 0xfe, 0x4e, 0x68, 0xd3, 0xb6, 0xb2, 0xbc, 0xfe, 0x68,
0xfe, 0xfe, 0x68, 0x54, 0x68, 0xe7, 0xc5, 0xbc, 0xb8, 0xbe,
0xcd, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xd3, 0xd3, 0xcd,
0xc1, 0xb8, 0xbc, 0xdb, 0x4e, 0x42, 0x4a, 0xfe, 0xc9, 0xc1,
0xcd, 0xd3, 0xcd, 0xba, 0xb8, 0xcd, 0x46, 0x3b, 0xfe, 0xc9,
0xba, 0xcd, 0xe7, 0xfe, 0xd3, 0xc1, 0xba, 0xdb, 0x54, 0x3d,
0x68, 0xd3, 0xbc, 0xcd, 0xfe, 0xfe, 0xc5, 0xbe, 0xc1, 0xe7,
0x54, 0x4a, 0xfe, 0xc9, 0xc1, 0xcd, 0xfe, 0xfe, 0xd3, 0xd3,
0xd3, 0xfe, 0xe7, 0xe7, 0xe7, 0xdb, 0xd3, 0xe7, 0xe7, 0xe7,
0xfe, 0xfe, 0xfe, 0xfe, 0xcd, 0xc9, 0xdb, 0xfe, 0xfe, 0xdb,
0xbe, 0xc9, 0xfe, 0x5c, 0xfe, 0xc9, 0xbc, 0xbe, 0xdb, 0x68,
0x5c, 0xdb, 0xc5, 0xd3, 0x54, 0x46, 0xfe, 0xbc, 0xb2, 0xb8,
0xdb, 0x68, 0x68, 0xe7, 0xcd, 0xdb, 0x5c, 0x54, 0xfe, 0xc1,
0xb8, 0xc1, 0xe7, 0xfe, 0xfe, 0xe7, 0xe7, 0xfe, 0xfe, 0xfe,
0xd3, 0xc5, 0xc1, 0xc5, 0xcd, 0xd3, 0xe7, 0xfe, 0x54, 0x4e,
0xfe, 0xd3, 0xcd, 0xd3, 0xd3, 0xc5, 0xc1, 0xc1, 0xe7, 0x5c,
0x4e, 0x5c, 0xd3, 0xc1, 0xcd, 0xfe, 0xfe, 0xcd, 0xba, 0xba,
0xe7, 0x4a, 0x4a, 0x68, 0xcd, 0xc5, 0xcd, 0xfe, 0xfe, 0xcd,
0xb8, 0xc1, 0xe7, 0x4e, 0x5c, 0xe7, 0xc1, 0xc9, 0xdb, 0xfe,
0xe7, 0xc9, 0xc5, 0xd3, 0xfe, 0x68, 0xfe, 0xdb, 0xd3, 0xe7,
0xfe, 0xfe, 0xcd, 0xc9, 0xcd, 0xd3, 0xd3, 0xd3, 0xcd, 0xe7,
0xfe, 0xfe, 0xe7, 0xc5, 0xc5, 0xe7, 0x68, 0x68, 0xe7, 0xc1,
0xc5, 0xfe, 0x5c, 0xfe, 0xd3, 0xc1, 0xd3, 0xfe, 0x68, 0xe7,
0xc5, 0xb6, 0xc5, 0xe7, 0x68, 0xfe, 0xcd, 0xc5, 0xe7, 0xfe,
0x54, 0xfe, 0xc9, 0xc5, 0xdb, 0xfe, 0xfe, 0xfe, 0xd3, 0xd3,
0xfe, 0xfe, 0xfe, 0xcd, 0xc1, 0xc1, 0xc9, 0xd3, 0xd3, 0xe7,
0xfe, 0xfe, 0xfe, 0xfe, 0xe7, 0xd3, 0xdb, 0xe7, 0xe7, 0xd3,
0xcd, 0xd3, 0xfe, 0xfe, 0xfe, 0xcd, 0xc5, 0xd3, 0xe7, 0xe7,
0xc9, 0xbc, 0xbe, 0xe7, 0x68, 0x4a, 0xfe, 0xdb, 0xcd, 0xfe,
0xfe, 0xfe, 0xcd, 0xc1, 0xc9, 0xfe, 0x54, 0x5c, 0xe7, 0xc9,
0xc5, 0xe7, 0xfe, 0xfe, 0xcd, 0xc5, 0xc5, 0xe7, 0xfe, 0xfe,
0xfe, 0xe7, 0xe7, 0xfe, 0xfe, 0xdb, 0xd3, 0xd3, 0xdb, 0xe7,
0xfe, 0xfe, 0xe7, 0xe7, 0xdb, 0xd3, 0xc9, 0xd3, 0xe7, 0xfe,
0xfe, 0xd3, 0xd3, 0xdb, 0xfe, 0xfe, 0xfe, 0xd3, 0xcd, 0xcd,
0xfe, 0xfe, 0xe7, 0xc9, 0xc5, 0xd3, 0xfe, 0xfe, 0xfe, 0xcd,
0xc9, 0xd3, 0xfe, 0xfe, 0xfe, 0xdb, 0xc9, 0xcd, 0xe7, 0xfe,
0xe7, 0xcd, 0xcd, 0xe7, 0xfe, 0xfe, 0xe7, 0xd3, 0xc5, 0xcd,
0xe7, 0xfe, 0xfe, 0xfe, 0xdb, 0xe7, 0xfe, 0xfe, 0xfe, 0xfe,
0xe7, 0xcd, 0xcd, 0xd3, 0xe7, 0xe7, 0xe7, 0xe7, 0xfe, 0xfe,
0xe7, 0xe7, 0xdb, 0xc9, 0xc1, 0xc5, 0xfe, 0x5c, 0x68, 0xfe,
0xd3, 0xdb, 0xe7, 0xe7, 0xe7, 0xd3, 0xc5, 0xcd, 0xe7, 0x68,
0xfe, 0xe7, 0xcd, 0xd3, 0xe7, 0xfe, 0xe7, 0xcd, 0xc1, 0xc1,
0xdb, 0xfe, 0x54, 0xfe, 0xe7, 0xcd, 0xe7, 0xfe, 0xe7, 0xd3,
0xcd, 0xd3, 0xe7, 0xfe, 0xfe, 0xfe, 0xcd, 0xc5, 0xcd, 0xfe,
0xfe, 0xe7, 0xcd, 0xd3, 0xdb, 0xe7, 0xfe, 0xfe, 0xfe, 0xe7,
0xd3, 0xd3, 0xe7, 0xfe, 0xe7, 0xe7, 0xe7, 0xfe, 0xfe, 0xfe,
0xfe, 0xdb, 0xc5, 0xc1, 0xd3, 0xfe, 0xfe, 0xfe, 0xd3, 0xc9,
0xcd, 0xe7, 0xfe, 0xfe, 0xd3, 0xcd, 0xdb, 0xfe, 0x5c, 0xfe,
0xcd, 0xc9, 0xd3, 0xfe, 0xfe, 0xfe, 0xd3, 0xc9, 0xcd, 0xfe,
0x68, 0xfe, 0xd3, 0xc1, 0xc1, 0xdb, 0xfe, 0xfe, 0xe7, 0xe7,
0xfe, 0xfe, 0x68, 0xfe, 0xe7, 0xc5, 0xc9, 0xdb, 0xfe, 0xfe,
0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xdb, 0xc5, 0xc5,
0xd3, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xe7, 0xe7, 0xfe, 0xfe,
0xc9, 0xc1, 0xc5, 0xfe, 0x54, 0x5c, 0xfe, 0xcd, 0xc5, 0xcd,
0xfe, 0xfe, 0xdb, 0xc5, 0xc9, 0xfe, 0x5c, 0x68, 0xfe, 0xcd,
0xcd, 0xfe, 0xfe, 0xfe, 0xe7, 0xc5, 0xc1, 0xd3, 0xfe, 0xfe,
0xdb, 0xc9, 0xc5, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xfe,
0xfe, 0xfe, 0xe7, 0xcd, 0xcd, 0xdb, 0xfe, 0xfe, 0xfe, 0xfe,
0xe7, 0xd3, 0xcd, 0xd3, 0xfe, 0xfe, 0xdb, 0xcd, 0xd3, 0xe7,
0xfe, 0xfe, 0xfe, 0xdb, 0xcd, 0xd3, 0xe7, 0xfe, 0xd3, 0xc5,
0xc9, 0xfe, 0x5c, 0x54, 0xfe, 0xcd, 0xc1, 0xcd, 0xe7, 0xfe,
0xfe, 0xd3, 0xcd, 0xfe, 0x54, 0x5c, 0xe7, 0xc1, 0xc1, 0xd3,
0xfe, 0xfe, 0xe7, 0xd3, 0xd3, 0xe7, 0xfe, 0xfe, 0xfe, 0xcd,
0xc5, 0xcd, 0xd3, 0xe7, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
0xe7, 0xd3, 0xcd, 0xc9, 0xcd, 0xe7, 0xfe, 0xfe, 0xfe, 0xdb,
0xc9, 0xcd, 0xe7, 0xfe, 0xe7, 0xc9, 0xc5, 0xdb, 0xfe, 0x5c,
0xfe, 0xe7, 0xcd, 0xcd, 0xe7, 0xfe, 0xe7, 0xc5, 0xc1, 0xd3,
0xfe, 0x5c, 0xfe, 0xcd, 0xc5, 0xcd, 0xe7, 0xfe, 0xfe, 0xe7,
0xd3, 0xe7, 0xfe, 0xfe, 0xe7, 0xcd, 0xcd, 0xdb, 0xfe, 0xfe,
0xfe, 0xe7, 0xe7, 0xe7, 0xe7, 0xfe, 0xe7, 0xdb, 0xcd, 0xd3,
0xd3, 0xdb, 0xfe, 0xfe, 0xfe, 0xfe, 0xdb, 0xd3, 0xdb, 0xe7,
0xe7, 0xdb, 0xd3, 0xe7, 0xfe, 0xfe, 0xfe, 0xe7, 0xc9, 0xc5,
0xcd, 0xe7, 0xfe, 0xdb, 0xd3, 0xe7, 0xfe, 0x68, 0xfe, 0xe7,
0xcd, 0xcd, 0xd3, 0xfe, 0xfe, 0xe7, 0xdb, 0xe7, 0xfe, 0x68,
0xfe, 0xdb, 0xfe, 0x68, 0xbe, 0xb2, 0xae, 0xab, 0xb2, 0xfe,
0x2f, 0x31, 0xdb, 0xac, 0xad, 0xaf, 0xab, 0xab, 0xb4, 0x68,
0x37, 0x39, 0x3f, 0xe7, 0xb4, 0xa8, 0xaa, 0xb0, 0xbc, 0xbc,
0xc5, 0x3f, 0x31, 0x3d, 0xfe, 0xc1, 0xb8, 0xb0, 0xa5, 0xa2,
0xa8, 0xaf, 0xdb, 0x3b, 0x28, 0x2a, 0x3d, 0xbc, 0xb0, 0xaa,
0xa2, 0x9f, 0xab, 0xfe, 0x29, 0x24, 0x29, 0x4a, 0xb4, 0xaa,
0xa8, 0xa9, 0xa8, 0xa5, 0xac, 0xdb, 0x2c, 0x27, 0x35, 0x4a,
0xfe, 0xcd, 0xb2, 0xa2, 0x9f, 0x9f, 0xae, 0x4e, 0x2c, 0x22,
0x33, 0xfe, 0xba, 0xb0, 0xa6, 0x9f, 0xa3, 0xbc, 0x5c, 0x33,
0x31, 0x39, 0x5c, 0xcd, 0xc1, 0xb4, 0xad, 0xaa, 0xad, 0xcd,
0x54, 0x46, 0xfe, 0xe7, 0xfe, 0x54, 0xc5, 0xaf, 0xa6, 0xa9,
0xb0, 0xfe, 0x3d, 0x39, 0x5c, 0xdb, 0xdb, 0xfe, 0xba, 0xac,
0xa8, 0xc5, 0x39, 0x33, 0x54, 0xb8, 0xae, 0xad, 0xb8, 0xc1,
0xcd, 0xbe, 0xbc, 0xfe, 0x39, 0x37, 0xfe, 0xb4, 0xba, 0xcd,
0xdb, 0xb8, 0xb0, 0xb6, 0xfe, 0x4e, 0x39, 0x3d, 0xfe, 0xb0,
0xaa, 0xa9, 0xa9, 0xaa, 0xb0, 0x5c, 0x29, 0x28, 0x31, 0xfe,
0xba, 0xb4, 0xae, 0xab, 0xab, 0xb2, 0xfe, 0x3b, 0x2a, 0x2f,
0x54, 0xb4, 0xb4, 0xba, 0xb2, 0xa3, 0x9f, 0xa8, 0xfe, 0x2c,
0x27, 0x2a, 0x46, 0xfe, 0xc1, 0xbc, 0xb0, 0xa2, 0xa2, 0xb0,
0x33, 0x22, 0x2b, 0x46, 0xc1, 0xb4, 0xb0, 0xab, 0xa8, 0xa8,
0xb0, 0xdb, 0x42, 0x2c, 0x33, 0x4a, 0xfe, 0x5c, 0xdb, 0xb4,
0xa8, 0xad, 0xba, 0xfe, 0x46, 0x39, 0x39, 0x4a, 0xfe, 0xbc,
0xab, 0xa5, 0xa5, 0xb8, 0x68, 0x37, 0x4a, 0xe7, 0xfe, 0x4a,
0x5c, 0xd3, 0xb0, 0xb2, 0xc1, 0x5c, 0x42, 0x46, 0xd3, 0xb4,
0xbe, 0x54, 0x54, 0xb6, 0xab, 0xae, 0xe7, 0x46, 0x4a, 0xfe,
0xcd, 0xc9, 0xd3, 0xe7, 0xe7, 0xbe, 0xb4, 0xc5, 0x37, 0x2c,
0x37, 0xc1, 0xb0, 0xb2, 0xb4, 0xb2, 0xb6, 0xdb, 0x54, 0x4a,
0x46, 0x42, 0x68, 0xba, 0xb2, 0xba, 0xc5, 0xb6, 0xb6, 0xcd,
0x33, 0x2f, 0x39, 0x68, 0xfe, 0xe7, 0xba, 0xac, 0xa7, 0xa7,
0xb2, 0xe7, 0x2d, 0x25, 0x2f, 0xd3, 0xbe, 0xd3, 0xc5, 0xac,
0xa6, 0xac, 0xfe, 0x33, 0x2c, 0x2d, 0x54, 0xc1, 0xb4, 0xcd,
0xcd, 0xaf, 0xa4, 0xa8, 0xe7, 0x31, 0x31, 0x39, 0x46, 0xfe,
0xdb, 0xbc, 0xb6, 0xaf, 0xa9, 0xb2, 0xfe, 0x2f, 0xfe, 0xba,
0xad, 0xba, 0x4e, 0x3d, 0x42, 0xfe, 0xc9, 0xc1, 0xe7, 0xfe,
0xc1, 0xa9, 0xa6, 0xcd, 0x2a, 0x25, 0x3b, 0xbc, 0xb0, 0xb6,
0xb8, 0xb4, 0xb4, 0xb8, 0xc1, 0xfe, 0x3d, 0x3d, 0xfe, 0xba,
0xd3, 0x54, 0x54, 0xbe, 0xb0, 0xb4, 0xe7, 0xfe, 0xfe, 0xfe,
0xfe, 0xfe, 0xfe, 0xc5, 0xb6, 0xa9, 0xaa, 0xba, 0x3d, 0x39,
0xfe, 0xc1, 0xfe, 0x4a, 0x54, 0xbe, 0xb2, 0xb8, 0xfe, 0x3d,
0x3b, 0xfe, 0xb0, 0xab, 0xc5, 0x39, 0x3b, 0xbc, 0xa7, 0xab,
0xd3, 0x68, 0xfe, 0xd3, 0xcd, 0xfe, 0x54, 0x3d, 0xfe, 0xbc,
0xac, 0xc9, 0x3f, 0x2e, 0xfe, 0xba, 0xb0, 0xba, 0xba, 0xb6,
0xba, 0xd3, 0xfe, 0xfe, 0x5c, 0x54, 0xc9, 0xb4, 0xbe, 0x54,
0x68, 0xcd, 0xb6, 0xfe, 0x46, 0x54, 0xcd, 0xc5, 0xdb, 0xfe,
0xe7, 0xc1, 0xae, 0xa8, 0xac, 0xfe, 0x2e, 0x2e, 0xfe, 0xb6,
0xc1, 0x5c, 0xe7, 0xb6, 0xaa, 0xb0, 0x54, 0x35, 0x2e, 0x4a,
0xc1, 0xac, 0xbc, 0xfe, 0xfe, 0xaf, 0xa6, 0xac, 0xfe, 0x42,
0x46, 0x5c, 0xfe, 0xfe, 0xfe, 0xe7, 0xc9, 0xae, 0xa9, 0xb0,
0x54, 0x31, 0x37, 0xfe, 0xd3, 0xd3, 0xb8, 0xac, 0xab, 0xb6,
0xe7, 0xfe, 0xfe, 0x68, 0xfe, 0xfe, 0xfe, 0x54, 0xfe, 0xb0,
0xae, 0xb8, 0xfe, 0xe7, 0xc1, 0xb6, 0xe7, 0x46, 0x3d, 0xe7,
0xae, 0xa7, 0xab, 0xdb, 0x3f, 0x37, 0xfe, 0xba, 0xcd, 0x3f,
0x42, 0xc5, 0xab, 0xac, 0xc9, 0x46, 0x3d, 0x54, 0xba, 0xad,
0xb0, 0xfe, 0x68, 0xcd, 0xb0, 0xb0, 0xc9, 0x54, 0x54, 0xfe,
0xfe, 0xfe, 0xfe, 0xe7, 0xcd, 0xbe, 0xba, 0xc5, 0x68, 0x42,
0x46, 0xe7, 0xc5, 0xba, 0xaf, 0xa7, 0xa7, 0xbc, 0xfe, 0x3d,
0x4a, 0x68, 0xfe, 0xfe, 0xfe, 0xe7, 0xbc, 0xaf, 0xae, 0xc5,
0x3d, 0x39, 0xfe, 0xbc, 0xbe, 0xfe, 0x68, 0xc9, 0xa9, 0xa2,
0xaa, 0xbc, 0x3b, 0x2d, 0x35, 0xfe, 0xcd, 0xfe, 0xfe, 0xb4,
0xa9, 0xa6, 0xbc, 0x54, 0x31, 0x31, 0x54, 0xd3, 0xbc, 0xc5,
0xcd, 0xb8, 0xab, 0xa8, 0xb4, 0xfe, 0x54, 0x4e, 0x68, 0x54,
0xfe, 0xc9, 0xba, 0xb4, 0xb4, 0xba, 0xcd, 0x5c, 0x3b, 0x3f,
0x54, 0xfe, 0xcd, 0xaf, 0xa8, 0xac, 0xc5, 0x68, 0xfe, 0xe7,
0xdb, 0xfe, 0xfe, 0xfe, 0xcd, 0xb8, 0xaf, 0xb6, 0xe7, 0x42,
0x5c, 0xcd, 0xbc, 0xfe, 0x46, 0x68, 0xba, 0xb0, 0xab, 0xbc,
0x54, 0x3d, 0x46, 0xc9, 0xb8, 0xbc, 0xdb, 0xd3, 0xb6, 0xb0,
0xb6, 0x5c, 0x37, 0x35, 0x54, 0xc9, 0xba, 0xb4, 0xc1, 0xc9,
0xc1, 0xba, 0xe7, 0x5c, 0x3d, 0x54, 0xfe, 0xcd, 0xc5, 0xb8,
0xae, 0xaf, 0xb4, 0xd3, 0x54, 0x3b, 0x35, 0x46, 0xfe, 0xdb,
0xbc, 0xaf, 0xa9, 0xab, 0xd3, 0x3f, 0x31, 0x3f, 0xfe, 0xe7,
0xdb, 0xcd, 0xb8, 0xae, 0xaa, 0xac, 0xe7, 0x33, 0x2d, 0x3f,
0xd3, 0xdb, 0xfe, 0xfe, 0xbc, 0xaa, 0xa9, 0xb0, 0xfe, 0x31,
0x2f, 0x3d, 0xdb, 0xc5, 0xcd, 0xc9, 0xae, 0xa8, 0xad, 0xfe,
0x46, 0x39, 0x46, 0x5c, 0xfe, 0xcd, 0xc5, 0xc1, 0xb6, 0xb0,
0xbc, 0x68, 0x42, 0x4e, 0xe7, 0xfe, 0x5c, 0xfe, 0xb6, 0xaf,
0xb0, 0xc5, 0xe7, 0x5c, 0x5c, 0xfe, 0xe7, 0xfe, 0x68, 0xe7,
0xb0, 0xac, 0xb2, 0x4a, 0x35, 0x3f, 0xcd, 0xbc, 0xc1, 0xe7,
0xe7, 0xd3, 0xb6, 0xb4, 0xfe, 0x3b, 0x33, 0xfe, 0xba, 0xb4,
0xd3, 0xfe, 0xc9, 0xb4, 0xb4, 0xcd, 0x4a, 0x3b, 0x3b, 0xfe,
0xb8, 0xb6, 0xc5, 0xc5, 0xb8, 0xb0, 0xcd, 0x4a, 0x31, 0x3b,
0x68, 0xcd, 0xc1, 0xba, 0xb4, 0xb0, 0xb0, 0xba, 0x5c, 0x2f,
0x2f, 0x4e, 0xc9, 0xc1, 0xdb, 0xc9, 0xb4 };

View File

@@ -1,207 +0,0 @@
/*
* U-law 8-bit audio data
*
* Source: leave.raw
*
* Copyright (C) 1999, Mark Spencer and Linux Support Services
*
* Distributed under the terms of the GNU General Public License
*
*/
static unsigned char leave[] = {
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xc1, 0x3d,
0x42, 0x46, 0x3f, 0x3f, 0x46, 0x3f, 0x4e, 0xba, 0xbe, 0xbe,
0xbc, 0xba, 0xbe, 0xc5, 0xb6, 0x2e, 0x2c, 0x33, 0x2f, 0x2e,
0x2f, 0x33, 0x2b, 0x54, 0xac, 0xb0, 0xb0, 0xad, 0xaf, 0xb0,
0xae, 0xcd, 0x3b, 0x2f, 0x31, 0x2e, 0x2f, 0x31, 0x2e, 0x46,
0xc5, 0xaf, 0xb0, 0xaf, 0xae, 0xaf, 0xaf, 0xb0, 0xfe, 0x2d,
0x31, 0x31, 0x2e, 0x31, 0x2f, 0x31, 0xfe, 0xae, 0xaf, 0xaf,
0xae, 0xb0, 0xae, 0xaf, 0xfe, 0xdb, 0x2e, 0x2e, 0x31, 0x31,
0x2d, 0x2e, 0xdb, 0x68, 0xaf, 0xad, 0xb0, 0xb0, 0xae, 0xaf,
0x5c, 0xe7, 0x39, 0x2d, 0x31, 0x31, 0x31, 0x2d, 0xfe, 0xfe,
0x68, 0xad, 0xaf, 0xb0, 0xaf, 0xac, 0xbc, 0xfe, 0xd3, 0x2f,
0x2e, 0x33, 0x31, 0x2d, 0x4e, 0xdb, 0xfe, 0xfe, 0xac, 0xaf,
0xb0, 0xac, 0xb6, 0x68, 0xe7, 0xdb, 0x2e, 0x2f, 0x35, 0x2f,
0x31, 0xe7, 0xe7, 0x68, 0xad, 0xac, 0xb0, 0xae, 0xac, 0xfe,
0xfe, 0xdb, 0xfe, 0x2d, 0x33, 0x31, 0x2e, 0xfe, 0xfe, 0xfe,
0xfe, 0xbc, 0xaf, 0xb0, 0xad, 0xfe, 0xfe, 0xfe, 0xe7, 0x5c,
0x2e, 0x33, 0x2e, 0x35, 0xe7, 0xfe, 0xfe, 0xfe, 0xad, 0xb0,
0xaf, 0xc1, 0xfe, 0xe7, 0xfe, 0xe7, 0x3d, 0x31, 0x2f, 0x37,
0xe7, 0xfe, 0xfe, 0xe7, 0xfe, 0xaf, 0xad, 0xbe, 0xfe, 0xdb,
0xfe, 0xfe, 0xdb, 0x35, 0x2d, 0x39, 0xdb, 0xfe, 0xfe, 0xdb,
0xfe, 0xfe, 0xad, 0xaf, 0xfe, 0xfe, 0xe7, 0x68, 0xfe, 0xd3,
0x2e, 0x2c, 0xdb, 0xdb, 0x2c, 0x35, 0xd3, 0x68, 0xaf, 0xad,
0xb0, 0xb0, 0xad, 0xba, 0x68, 0xe7, 0xe7, 0x2e, 0x2f, 0x33,
0x31, 0x2d, 0xdb, 0xd3, 0x5c, 0xae, 0xaa, 0xe7, 0x68, 0xaa,
0xe7, 0xfe, 0xdb, 0xe7, 0xfe, 0xe7, 0xd3, 0x2d, 0xfe, 0xdb,
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xc5, 0xfe, 0xe7, 0xe7,
0xfe, 0xfe, 0xe7, 0xe7, 0x3b, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
0xfe, 0xfe, 0xe7, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
0xc5, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xe7, 0xfe, 0x3b,
0xdb, 0xfe, 0xfe, 0xfe, 0xe7, 0xfe, 0xfe, 0xb0, 0xfe, 0xfe,
0xe7, 0xfe, 0xfe, 0xfe, 0xdb, 0x2e, 0x5c, 0xdb, 0xfe, 0xfe,
0xe7, 0xe7, 0x68, 0xb0, 0xbe, 0x68, 0xe7, 0xe7, 0xfe, 0xfe,
0xdb, 0x39, 0x2f, 0xdb, 0xfe, 0xfe, 0xe7, 0xe7, 0xfe, 0xbe,
0xaf, 0xe7, 0x68, 0xe7, 0xfe, 0xfe, 0xfe, 0xfe, 0x33, 0x33,
0xdb, 0xfe, 0xfe, 0xdb, 0xe7, 0xfe, 0xb0, 0xb0, 0xfe, 0xfe,
0xe7, 0xfe, 0xfe, 0xfe, 0x35, 0x33, 0xe7, 0xe7, 0xfe, 0xe7,
0xe7, 0xfe, 0xb0, 0xb2, 0xb0, 0xfe, 0xfe, 0xe7, 0xfe, 0xe7,
0x46, 0x35, 0x35, 0x3f, 0xe7, 0xfe, 0xe7, 0xfe, 0xb2, 0xb0,
0xb2, 0xb0, 0xfe, 0xfe, 0xfe, 0xfe, 0x42, 0x35, 0x37, 0x33,
0xe7, 0xfe, 0xfe, 0xfe, 0xb8, 0xb0, 0xb6, 0xb0, 0xba, 0xfe,
0xfe, 0xe7, 0xe7, 0x33, 0x39, 0x39, 0x33, 0xe7, 0xdb, 0xfe,
0xe7, 0xb0, 0xb4, 0xb6, 0xb0, 0xcd, 0xfe, 0xe7, 0xe7, 0x33,
0x39, 0x3b, 0x33, 0x46, 0xd3, 0xfe, 0xfe, 0xb0, 0xb2, 0xb6,
0xb4, 0xb0, 0xfe, 0xfe, 0xdb, 0x35, 0x37, 0x39, 0x39, 0x35,
0x37, 0xdb, 0x68, 0xcd, 0xb2, 0xb6, 0xb6, 0xb4, 0xb4, 0x68,
0xe7, 0x42, 0x37, 0x3b, 0x3b, 0x39, 0x37, 0xdb, 0xfe, 0xcd,
0xb2, 0xb6, 0xb6, 0xb6, 0xb2, 0xb4, 0xfe, 0x54, 0x37, 0x3b,
0x39, 0x3b, 0x3b, 0x39, 0xe7, 0xfe, 0xb6, 0xb6, 0xb6, 0xb4,
0xb6, 0xb6, 0xbc, 0xfe, 0x3f, 0x3b, 0x3b, 0x39, 0x3b, 0x3b,
0x39, 0xe7, 0xb6, 0xb8, 0xb8, 0xb6, 0xb8, 0xb8, 0xb4, 0xfe,
0x3b, 0x3d, 0x3d, 0x3b, 0x39, 0x3d, 0x3b, 0x39, 0xbe, 0xb8,
0xba, 0xb8, 0xb6, 0xb8, 0xba, 0xb4, 0xfe, 0x39, 0x3f, 0x3d,
0x3b, 0x3d, 0x3f, 0x39, 0xdb, 0xb4, 0xba, 0xb8, 0xb6, 0xb8,
0xbc, 0xb4, 0xba, 0x39, 0x42, 0x3f, 0x3d, 0x3d, 0x3f, 0x3f,
0x3b, 0xb8, 0xb6, 0xbc, 0xb8, 0xb8, 0xba, 0xbc, 0xb8, 0xe7,
0x3d, 0x42, 0x3f, 0x3d, 0x3f, 0x42, 0x3d, 0xfe, 0xb8, 0xbc,
0xbc, 0xba, 0xba, 0xbc, 0xba, 0xe7, 0x3d, 0x3f, 0x42, 0x3f,
0x3f, 0x42, 0x42, 0xfe, 0xfe, 0xbc, 0xbc, 0xbe, 0xbc, 0xbe,
0xbc, 0xc5, 0xe7, 0x68, 0x42, 0x46, 0x42, 0x46, 0x42, 0x46,
0xfe, 0xfe, 0xbc, 0xbe, 0xbe, 0xbe, 0xbc, 0xc5, 0xfe, 0xdb,
0x46, 0x46, 0x4a, 0x4a, 0x46, 0x46, 0xe7, 0xfe, 0xd3, 0xbe,
0xc9, 0xc9, 0xc5, 0xc5, 0xe7, 0xdb, 0xd3, 0x4a, 0x4e, 0x54,
0x4e, 0x4e, 0xfe, 0x5c, 0x54, 0xd3, 0xcd, 0xd3, 0xd3, 0xcd,
0xd3, 0xd3, 0xcd, 0xfe, 0x5c, 0x68, 0x5c, 0x5c, 0x5c, 0x68,
0x5c, 0x5c, 0xcd, 0xcd, 0xd3, 0xcd, 0xdb, 0xe7, 0xe7, 0xdb,
0xe7, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xe7,
0xfe, 0x5c, 0x5c, 0xfe, 0xfe, 0xfe, 0xfe, 0x46, 0x35, 0x35,
0x37, 0x39, 0x3b, 0x39, 0x35, 0x33, 0x35, 0x5c, 0xd3, 0xcd,
0xdb, 0xfe, 0xfe, 0xd3, 0xb0, 0xb0, 0xb0, 0xb4, 0xb4, 0xb6,
0xb2, 0xb0, 0xb0, 0xb6, 0xcd, 0x5c, 0x68, 0xfe, 0xfe, 0xfe,
0x3b, 0x33, 0x35, 0x37, 0x39, 0x3b, 0x39, 0x37, 0x35, 0x35,
0x3f, 0xdb, 0xcd, 0xcd, 0xdb, 0xfe, 0xe7, 0xc5, 0xb0, 0xb0,
0xb2, 0xb6, 0xb6, 0xb6, 0xb2, 0xb0, 0xb0, 0xcd, 0x5c, 0x5c,
0xfe, 0xe7, 0xe7, 0xfe, 0x35, 0x35, 0x35, 0x39, 0x3b, 0x3b,
0x39, 0x35, 0x33, 0x39, 0xdb, 0xcd, 0xd3, 0xe7, 0xfe, 0xfe,
0xba, 0xb0, 0xb0, 0xb2, 0xb4, 0xb6, 0xb6, 0xb4, 0xb2, 0xb0,
0xb4, 0xc9, 0x5c, 0x68, 0xfe, 0xfe, 0x5c, 0x3b, 0x35, 0x37,
0x39, 0x3b, 0x3b, 0x3b, 0x39, 0x37, 0x37, 0x3d, 0xe7, 0xcd,
0xdb, 0xfe, 0xe7, 0xbe, 0xb2, 0xb2, 0xb4, 0xb4, 0xb6, 0xb6,
0xb6, 0xb4, 0xb0, 0xb0, 0xc5, 0x5c, 0x5c, 0xfe, 0xe7, 0xe7,
0x4e, 0x35, 0x35, 0x37, 0x3b, 0x3b, 0x3b, 0x39, 0x37, 0x37,
0x3b, 0xe7, 0xc9, 0xcd, 0xe7, 0xfe, 0xd3, 0xb4, 0xb2, 0xb2,
0xb4, 0xb6, 0xb6, 0xb6, 0xb6, 0xb4, 0xb2, 0xb4, 0xc1, 0x68,
0x68, 0xfe, 0xfe, 0x42, 0x39, 0x37, 0x39, 0x3b, 0x3b, 0x3b,
0x3b, 0x3b, 0x39, 0x37, 0x3b, 0xfe, 0xd3, 0xdb, 0xfe, 0xcd,
0xb4, 0xb2, 0xb4, 0xb4, 0xb6, 0xb6, 0xb6, 0xb6, 0xb4, 0xb2,
0xb2, 0xc1, 0x5c, 0x5c, 0xfe, 0xfe, 0xfe, 0x3d, 0x37, 0x37,
0x39, 0x3b, 0x3b, 0x3b, 0x3b, 0x37, 0x37, 0x39, 0xfe, 0xcd,
0xd3, 0xfe, 0xfe, 0xc1, 0xb2, 0xb2, 0xb4, 0xb6, 0xb6, 0xb6,
0xb6, 0xb6, 0xb6, 0xb4, 0xb4, 0xbc, 0x68, 0xfe, 0xfe, 0xfe,
0x3b, 0x39, 0x39, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x39,
0x39, 0x3b, 0xfe, 0xdb, 0xe7, 0xfe, 0xbc, 0xb6, 0xb6, 0xb6,
0xb8, 0xb6, 0xb6, 0xb6, 0xb8, 0xb6, 0xb4, 0xb4, 0xbc, 0xfe,
0x68, 0xfe, 0xe7, 0x5c, 0x3b, 0x39, 0x39, 0x3b, 0x3b, 0x3b,
0x3d, 0x3d, 0x3b, 0x39, 0x3b, 0x68, 0xdb, 0xdb, 0xfe, 0xe7,
0xb8, 0xb6, 0xb6, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb6,
0xb4, 0xb6, 0xdb, 0x68, 0xfe, 0xfe, 0x46, 0x3b, 0x3b, 0x3b,
0x3d, 0x3d, 0x3b, 0x3d, 0x3d, 0x3d, 0x3d, 0x3b, 0x3b, 0x5c,
0xdb, 0xdb, 0xc9, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8,
0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xbc, 0xcd, 0xfe, 0xfe, 0x3d,
0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3b, 0x3d, 0x3d, 0x3d, 0x3d,
0x3b, 0x3d, 0x46, 0xfe, 0xe7, 0xe7, 0xc5, 0xb8, 0xb8, 0xb8,
0xba, 0xba, 0xb8, 0xb8, 0xba, 0xba, 0xb8, 0xb8, 0xb8, 0xcd,
0xfe, 0xfe, 0x68, 0x3f, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d,
0x3d, 0x3d, 0x3f, 0x3f, 0x3d, 0x3b, 0x4a, 0xfe, 0xdb, 0xbc,
0xb8, 0xba, 0xba, 0xba, 0xba, 0xb8, 0xb8, 0xb8, 0xba, 0xba,
0xba, 0xba, 0xba, 0xc5, 0xfe, 0x54, 0x3f, 0x3f, 0x3f, 0x3f,
0x3f, 0x3f, 0x3d, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x42,
0xfe, 0xe7, 0xdb, 0xbc, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba,
0xba, 0xba, 0xbc, 0xba, 0xba, 0xba, 0xc5, 0xfe, 0xfe, 0x4e,
0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x42,
0x42, 0x42, 0x3f, 0x46, 0xfe, 0xcd, 0xb8, 0xba, 0xbc, 0xbc,
0xbc, 0xba, 0xba, 0xba, 0xba, 0xbc, 0xbc, 0xbc, 0xba, 0xb8,
0xbe, 0xfe, 0x42, 0x3d, 0x3f, 0x42, 0x42, 0x42, 0x3f, 0x3f,
0x3f, 0x42, 0x42, 0x42, 0x42, 0x3f, 0x3f, 0x68, 0xdb, 0xc5,
0xba, 0xbc, 0xbc, 0xbc, 0xbc, 0xba, 0xba, 0xba, 0xbc, 0xbc,
0xbc, 0xbc, 0xba, 0xc1, 0xfe, 0xfe, 0x3f, 0x42, 0x46, 0x46,
0x46, 0x42, 0x42, 0x42, 0x42, 0x42, 0x46, 0x46, 0x42, 0x3f,
0x42, 0x68, 0xbe, 0xba, 0xbc, 0xbe, 0xbe, 0xbe, 0xbc, 0xbc,
0xbc, 0xbc, 0xbe, 0xc1, 0xbe, 0xbc, 0xba, 0xbe, 0x68, 0x3f,
0x42, 0x46, 0x4a, 0x4a, 0x46, 0x42, 0x42, 0x42, 0x46, 0x46,
0x46, 0x46, 0x42, 0x42, 0x68, 0xd3, 0xbc, 0xbc, 0xbe, 0xc1,
0xc1, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xc1, 0xc1, 0xbe, 0xbe,
0xc1, 0xfe, 0x4e, 0x42, 0x46, 0x4a, 0x4a, 0x4a, 0x46, 0x46,
0x46, 0x46, 0x4a, 0x4a, 0x4a, 0x46, 0x46, 0x68, 0xdb, 0xbe,
0xbe, 0xc1, 0xc5, 0xc1, 0xc1, 0xbe, 0xbe, 0xbe, 0xbe, 0xc1,
0xc5, 0xc5, 0xbe, 0xbc, 0xc1, 0x4e, 0x46, 0x46, 0x4a, 0x4e,
0x4e, 0x4a, 0x46, 0x46, 0x46, 0x4a, 0x4a, 0x4e, 0x4a, 0x46,
0x46, 0xfe, 0xbe, 0xbe, 0xc1, 0xc9, 0xc5, 0xc5, 0xc1, 0xc1,
0xc1, 0xc1, 0xc5, 0xc5, 0xc5, 0xc5, 0xbe, 0xc1, 0xfe, 0x4a,
0x4a, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4a, 0x4a, 0x4a, 0x4e,
0x54, 0x4e, 0x4a, 0x4a, 0x4e, 0xcd, 0xc1, 0xc5, 0xc5, 0xc9,
0xc5, 0xc5, 0xc5, 0xc5, 0xc9, 0xcd, 0xcd, 0xcd, 0xcd, 0xc9,
0xc9, 0xd3, 0x68, 0x54, 0x5c, 0x68, 0x68, 0x68, 0x5c, 0x5c,
0x5c, 0x5c, 0x5c, 0x68, 0x68, 0x5c, 0x54, 0x5c, 0xdb, 0xcd,
0xcd, 0xdb, 0xdb, 0xdb, 0xdb, 0xd3, 0xd3, 0xe7, 0xe7, 0xe7,
0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
0xfe, 0xfe, 0xe7, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
0xfe, 0xfe, 0xfe };

Binary file not shown.

View File

@@ -1,880 +0,0 @@
%{
/* Written by Pace Willisson (pace@blitz.com)
* and placed in the public domain.
*
* Largely rewritten by J.T. Conklin (jtc@wimsey.com)
*
* $FreeBSD: src/bin/expr/expr.y,v 1.16 2000/07/22 10:59:36 se Exp $
*/
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <locale.h>
#include <ctype.h>
#include <err.h>
#include <errno.h>
#include <regex.h>
#include <limits.h>
#include <asterisk/ast_expr.h>
#include <asterisk/logger.h>
#ifdef LONG_LONG_MIN
#define QUAD_MIN LONG_LONG_MIN
#endif
#ifdef LONG_LONG_MAX
#define QUAD_MAX LONG_LONG_MAX
#endif
# if ! defined(QUAD_MIN)
# define QUAD_MIN (-0x7fffffffffffffffL-1)
# endif
# if ! defined(QUAD_MAX)
# define QUAD_MAX (0x7fffffffffffffffL)
# endif
#define YYPARSE_PARAM kota
#define YYLEX_PARAM kota
/* #define ast_log fprintf
#define LOG_WARNING stderr */
enum valtype {
integer, numeric_string, string
} ;
struct val {
enum valtype type;
union {
char *s;
quad_t i;
} u;
} ;
struct parser_control {
struct val *result;
int pipa;
char *arg_orig;
char *argv;
char *ptrptr;
int firsttoken;
} ;
static int chk_div __P((quad_t, quad_t));
static int chk_minus __P((quad_t, quad_t, quad_t));
static int chk_plus __P((quad_t, quad_t, quad_t));
static int chk_times __P((quad_t, quad_t, quad_t));
static void free_value __P((struct val *));
static int is_zero_or_null __P((struct val *));
static int isstring __P((struct val *));
static struct val *make_integer __P((quad_t));
static struct val *make_str __P((const char *));
static struct val *op_and __P((struct val *, struct val *));
static struct val *op_colon __P((struct val *, struct val *));
static struct val *op_div __P((struct val *, struct val *));
static struct val *op_eq __P((struct val *, struct val *));
static struct val *op_ge __P((struct val *, struct val *));
static struct val *op_gt __P((struct val *, struct val *));
static struct val *op_le __P((struct val *, struct val *));
static struct val *op_lt __P((struct val *, struct val *));
static struct val *op_minus __P((struct val *, struct val *));
static struct val *op_ne __P((struct val *, struct val *));
static struct val *op_or __P((struct val *, struct val *));
static struct val *op_plus __P((struct val *, struct val *));
static struct val *op_rem __P((struct val *, struct val *));
static struct val *op_times __P((struct val *, struct val *));
static quad_t to_integer __P((struct val *));
static void to_string __P((struct val *));
/* uh, if I want to predeclare yylex with a YYLTYPE, I have to predeclare the yyltype... sigh */
typedef struct yyltype
{
int first_line;
int first_column;
int last_line;
int last_column;
} yyltype;
# define YYLTYPE yyltype
# define YYLTYPE_IS_TRIVIAL 1
static int ast_yyerror __P((const char *,YYLTYPE *, struct parser_control *));
#define ast_yyerror(x) ast_yyerror(x,&yyloc,kota)
%}
%pure-parser
%locations
/* %debug for when you are having big problems */
/* %name-prefix="ast_yy" */
%union
{
struct val *val;
}
%{
static int ast_yylex __P((YYSTYPE *, YYLTYPE *, struct parser_control *));
%}
%left <val> '|'
%left <val> '&'
%left <val> '=' '>' '<' GE LE NE
%left <val> '+' '-'
%left <val> '*' '/' '%'
%left <val> ':'
%token <val> TOKEN
%type <val> start expr
%%
start: expr { ((struct parser_control *)kota)->result = $$; }
;
expr: TOKEN
| '(' expr ')' { $$ = $2; @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;}
| expr '|' expr { $$ = op_or ($1, $3); @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;}
| expr '&' expr { $$ = op_and ($1, $3); @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;}
| expr '=' expr { $$ = op_eq ($1, $3); @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;}
| expr '>' expr { $$ = op_gt ($1, $3); @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;}
| expr '<' expr { $$ = op_lt ($1, $3); @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;}
| expr GE expr { $$ = op_ge ($1, $3); @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;}
| expr LE expr { $$ = op_le ($1, $3); @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;}
| expr NE expr { $$ = op_ne ($1, $3); @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;}
| expr '+' expr { $$ = op_plus ($1, $3); @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;}
| expr '-' expr { $$ = op_minus ($1, $3); @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;}
| expr '*' expr { $$ = op_times ($1, $3); @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;}
| expr '/' expr { $$ = op_div ($1, $3); @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;}
| expr '%' expr { $$ = op_rem ($1, $3); @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;}
| expr ':' expr { $$ = op_colon ($1, $3); @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0;}
;
%%
static struct val *
make_integer (i)
quad_t i;
{
struct val *vp;
vp = (struct val *) malloc (sizeof (*vp));
if (vp == NULL) {
ast_log(LOG_WARNING, "malloc() failed\n");
return(NULL);
}
vp->type = integer;
vp->u.i = i;
return vp;
}
static struct val *
make_str (s)
const char *s;
{
struct val *vp;
size_t i;
int isint;
vp = (struct val *) malloc (sizeof (*vp));
if (vp == NULL || ((vp->u.s = strdup (s)) == NULL)) {
ast_log(LOG_WARNING,"malloc() failed\n");
return(NULL);
}
for(i = 1, isint = isdigit(s[0]) || s[0] == '-';
isint && i < strlen(s);
i++)
{
if(!isdigit(s[i]))
isint = 0;
}
if (isint)
vp->type = numeric_string;
else
vp->type = string;
return vp;
}
static void
free_value (vp)
struct val *vp;
{
if (vp==NULL) {
return;
}
if (vp->type == string || vp->type == numeric_string)
free (vp->u.s);
free (vp);
}
static quad_t
to_integer (vp)
struct val *vp;
{
quad_t i;
if (vp == NULL) {
ast_log(LOG_WARNING,"vp==NULL in to_integer()\n");
return(0);
}
if (vp->type == integer)
return 1;
if (vp->type == string)
return 0;
/* vp->type == numeric_string, make it numeric */
errno = 0;
i = strtoq(vp->u.s, (char**)NULL, 10);
if (errno != 0) {
free(vp->u.s);
ast_log(LOG_WARNING,"overflow\n");
return(0);
}
free (vp->u.s);
vp->u.i = i;
vp->type = integer;
return 1;
}
static void
to_string (vp)
struct val *vp;
{
char *tmp;
if (vp->type == string || vp->type == numeric_string)
return;
tmp = malloc ((size_t)25);
if (tmp == NULL) {
ast_log(LOG_WARNING,"malloc() failed\n");
return;
}
sprintf (tmp, "%lld", (long long)vp->u.i);
vp->type = string;
vp->u.s = tmp;
}
static int
isstring (vp)
struct val *vp;
{
/* only TRUE if this string is not a valid integer */
return (vp->type == string);
}
static int
ast_yylex (YYSTYPE *lvalp, YYLTYPE *yylloc, struct parser_control *karoto)
{
char *p=0;
char *t1=0;
char savep = 0;
char *savepp = 0;
if (karoto->firsttoken==1) {
t1 = karoto->argv;
karoto->firsttoken = 0;
} else {
t1 = karoto->ptrptr;
}
while(*t1 && *t1 == ' ' ) /* we can remove worries about leading/multiple spaces being present */
t1++;
karoto->ptrptr = t1;
yylloc->first_column = t1 - karoto->argv;
while( *t1 && *t1 != ' ' && *t1 != '"') /* find the next space or quote */
t1++;
if( *t1 == ' ' )
{
*t1 = 0;
p = karoto->ptrptr;
karoto->ptrptr = t1+1;
yylloc->last_column = t1 - karoto->argv;
}
else if (*t1 == '"' )
{
/* opening quote. find the closing quote */
char *t2=t1+1;
while( *t2 && *t2 != '"')
t2++;
if( *t2 == '"' )
{
if( *(t2+1) == ' ' || *(t2+1) == 0 )
{
if( *(t2+1) )
{
*(t2+1) = 0;
karoto->ptrptr = t2+2;
}
else
{
karoto->ptrptr = t2+1;
}
}
else
{
/* hmmm. what if another token is here? */
/* maybe we can insert a space? */
savep = *(t2+1);
savepp = t2+1;
*(t2+1) = 0;
karoto->ptrptr = t2+1;
}
p = t1;
}
else
{
/* NOT GOOD -- no closing quote! */
p = t1;
karoto->ptrptr = t2;
}
yylloc->last_column = t2 - karoto->argv;
}
else if( *t1 == 0 )
{
if( t1 != karoto->ptrptr )
{
/* this is the last token */
p = karoto->ptrptr;
karoto->ptrptr = t1;
}
else
{
/* we are done. That was quick */
p = karoto->ptrptr;
yylloc->last_column = t1 - karoto->argv;
}
}
if( *p == 0 )
p = 0;
if (p==NULL) {
return (0);
}
if (strlen (p) == 1) {
if (strchr ("|&=<>+-*/%:()", *p))
return (*p);
} else if (strlen (p) == 2 && p[1] == '=') {
switch (*p) {
case '>': return (GE);
case '<': return (LE);
case '!': return (NE);
}
}
lvalp->val = make_str (p);
if( savep )
{
*savepp = savep; /* restore the null terminated string */
savepp = 0;
savep = 0;
}
return (TOKEN);
}
static int
is_zero_or_null (vp)
struct val *vp;
{
if (vp->type == integer) {
return (vp->u.i == 0);
} else {
return (*vp->u.s == 0 || (to_integer (vp) && vp->u.i == 0));
}
/* NOTREACHED */
}
char *ast_expr (char *arg)
{
struct parser_control karoto;
char *kota;
char *pirouni;
kota=strdup(arg);
karoto.result = NULL;
karoto.firsttoken=1;
karoto.argv=kota;
karoto.arg_orig = arg;
/* ast_yydebug = 1; */
ast_yyparse ((void *)&karoto);
free(kota);
if (karoto.result==NULL) {
pirouni=strdup("0");
return(pirouni);
} else {
if (karoto.result->type == integer) {
pirouni=malloc(256);
sprintf (pirouni,"%lld", (long long)karoto.result->u.i);
}
else {
pirouni=strdup(karoto.result->u.s);
}
free(karoto.result);
}
return(pirouni);
}
#ifdef STANDALONE
int main(int argc,char **argv) {
char *s;
s=ast_expr(argv[1]);
printf("=====%s======\n",s);
}
#endif
#undef ast_yyerror
#define ast_yyerror(x) ast_yyerror(x, YYLTYPE *yylloc, struct parser_control *karoto)
static int
ast_yyerror (const char *s)
{
char spacebuf[8000]; /* best safe than sorry */
char spacebuf2[8000]; /* best safe than sorry */
int i=0;
spacebuf[0] = 0;
if( yylloc->first_column > 7990 ) /* if things get out of whack, why crash? */
yylloc->first_column = 7990;
if( yylloc->last_column > 7990 )
yylloc->last_column = 7990;
for(i=0;i<yylloc->first_column;i++) spacebuf[i] = ' ';
for( ;i<yylloc->last_column;i++) spacebuf[i] = '^';
spacebuf[i] = 0;
for(i=0;i<karoto->ptrptr-karoto->argv;i++) spacebuf2[i] = ' ';
spacebuf2[i++]='^';
spacebuf2[i]= 0;
ast_log(LOG_WARNING,"ast_yyerror(): syntax error: %s; Input:\n%s\n%s\n%s\n",s,
karoto->arg_orig,spacebuf,spacebuf2);
return(0);
}
static struct val *
op_or (a, b)
struct val *a, *b;
{
if (is_zero_or_null (a)) {
free_value (a);
return (b);
} else {
free_value (b);
return (a);
}
}
static struct val *
op_and (a, b)
struct val *a, *b;
{
if (is_zero_or_null (a) || is_zero_or_null (b)) {
free_value (a);
free_value (b);
return (make_integer ((quad_t)0));
} else {
free_value (b);
return (a);
}
}
static struct val *
op_eq (a, b)
struct val *a, *b;
{
struct val *r;
if (isstring (a) || isstring (b)) {
to_string (a);
to_string (b);
r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) == 0));
} else {
(void)to_integer(a);
(void)to_integer(b);
r = make_integer ((quad_t)(a->u.i == b->u.i));
}
free_value (a);
free_value (b);
return r;
}
static struct val *
op_gt (a, b)
struct val *a, *b;
{
struct val *r;
if (isstring (a) || isstring (b)) {
to_string (a);
to_string (b);
r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) > 0));
} else {
(void)to_integer(a);
(void)to_integer(b);
r = make_integer ((quad_t)(a->u.i > b->u.i));
}
free_value (a);
free_value (b);
return r;
}
static struct val *
op_lt (a, b)
struct val *a, *b;
{
struct val *r;
if (isstring (a) || isstring (b)) {
to_string (a);
to_string (b);
r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) < 0));
} else {
(void)to_integer(a);
(void)to_integer(b);
r = make_integer ((quad_t)(a->u.i < b->u.i));
}
free_value (a);
free_value (b);
return r;
}
static struct val *
op_ge (a, b)
struct val *a, *b;
{
struct val *r;
if (isstring (a) || isstring (b)) {
to_string (a);
to_string (b);
r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) >= 0));
} else {
(void)to_integer(a);
(void)to_integer(b);
r = make_integer ((quad_t)(a->u.i >= b->u.i));
}
free_value (a);
free_value (b);
return r;
}
static struct val *
op_le (a, b)
struct val *a, *b;
{
struct val *r;
if (isstring (a) || isstring (b)) {
to_string (a);
to_string (b);
r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) <= 0));
} else {
(void)to_integer(a);
(void)to_integer(b);
r = make_integer ((quad_t)(a->u.i <= b->u.i));
}
free_value (a);
free_value (b);
return r;
}
static struct val *
op_ne (a, b)
struct val *a, *b;
{
struct val *r;
if (isstring (a) || isstring (b)) {
to_string (a);
to_string (b);
r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) != 0));
} else {
(void)to_integer(a);
(void)to_integer(b);
r = make_integer ((quad_t)(a->u.i != b->u.i));
}
free_value (a);
free_value (b);
return r;
}
static int
chk_plus (a, b, r)
quad_t a, b, r;
{
/* sum of two positive numbers must be positive */
if (a > 0 && b > 0 && r <= 0)
return 1;
/* sum of two negative numbers must be negative */
if (a < 0 && b < 0 && r >= 0)
return 1;
/* all other cases are OK */
return 0;
}
static struct val *
op_plus (a, b)
struct val *a, *b;
{
struct val *r;
if (!to_integer (a)) {
ast_log(LOG_WARNING,"non-numeric argument\n");
if (!to_integer (b)) {
free_value(a);
free_value(b);
return make_integer(0);
} else {
free_value(a);
return (b);
}
} else if (!to_integer(b)) {
free_value(b);
return (a);
}
r = make_integer (/*(quad_t)*/(a->u.i + b->u.i));
if (chk_plus (a->u.i, b->u.i, r->u.i)) {
ast_log(LOG_WARNING,"overflow\n");
}
free_value (a);
free_value (b);
return r;
}
static int
chk_minus (a, b, r)
quad_t a, b, r;
{
/* special case subtraction of QUAD_MIN */
if (b == QUAD_MIN) {
if (a >= 0)
return 1;
else
return 0;
}
/* this is allowed for b != QUAD_MIN */
return chk_plus (a, -b, r);
}
static struct val *
op_minus (a, b)
struct val *a, *b;
{
struct val *r;
if (!to_integer (a)) {
ast_log(LOG_WARNING, "non-numeric argument\n");
if (!to_integer (b)) {
free_value(a);
free_value(b);
return make_integer(0);
} else {
r = make_integer(0 - b->u.i);
free_value(a);
free_value(b);
return (r);
}
} else if (!to_integer(b)) {
ast_log(LOG_WARNING, "non-numeric argument\n");
free_value(b);
return (a);
}
r = make_integer (/*(quad_t)*/(a->u.i - b->u.i));
if (chk_minus (a->u.i, b->u.i, r->u.i)) {
ast_log(LOG_WARNING, "overflow\n");
}
free_value (a);
free_value (b);
return r;
}
static int
chk_times (a, b, r)
quad_t a, b, r;
{
/* special case: first operand is 0, no overflow possible */
if (a == 0)
return 0;
/* cerify that result of division matches second operand */
if (r / a != b)
return 1;
return 0;
}
static struct val *
op_times (a, b)
struct val *a, *b;
{
struct val *r;
if (!to_integer (a) || !to_integer (b)) {
free_value(a);
free_value(b);
ast_log(LOG_WARNING, "non-numeric argument\n");
return(make_integer(0));
}
r = make_integer (/*(quad_t)*/(a->u.i * b->u.i));
if (chk_times (a->u.i, b->u.i, r->u.i)) {
ast_log(LOG_WARNING, "overflow\n");
}
free_value (a);
free_value (b);
return (r);
}
static int
chk_div (a, b)
quad_t a, b;
{
/* div by zero has been taken care of before */
/* only QUAD_MIN / -1 causes overflow */
if (a == QUAD_MIN && b == -1)
return 1;
/* everything else is OK */
return 0;
}
static struct val *
op_div (a, b)
struct val *a, *b;
{
struct val *r;
if (!to_integer (a)) {
free_value(a);
free_value(b);
ast_log(LOG_WARNING, "non-numeric argument\n");
return make_integer(0);
} else if (!to_integer (b)) {
free_value(a);
free_value(b);
ast_log(LOG_WARNING, "non-numeric argument\n");
return make_integer(INT_MAX);
}
if (b->u.i == 0) {
ast_log(LOG_WARNING, "division by zero\n");
free_value(a);
free_value(b);
return make_integer(INT_MAX);
}
r = make_integer (/*(quad_t)*/(a->u.i / b->u.i));
if (chk_div (a->u.i, b->u.i)) {
ast_log(LOG_WARNING, "overflow\n");
}
free_value (a);
free_value (b);
return r;
}
static struct val *
op_rem (a, b)
struct val *a, *b;
{
struct val *r;
if (!to_integer (a) || !to_integer (b)) {
ast_log(LOG_WARNING, "non-numeric argument\n");
free_value(a);
free_value(b);
return make_integer(0);
}
if (b->u.i == 0) {
ast_log(LOG_WARNING, "div by zero\n");
free_value(a);
return (b);
}
r = make_integer (/*(quad_t)*/(a->u.i % b->u.i));
/* chk_rem necessary ??? */
free_value (a);
free_value (b);
return r;
}
static struct val *
op_colon (a, b)
struct val *a, *b;
{
regex_t rp;
regmatch_t rm[2];
char errbuf[256];
int eval;
struct val *v;
/* coerce to both arguments to strings */
to_string(a);
to_string(b);
/* compile regular expression */
if ((eval = regcomp (&rp, b->u.s, REG_EXTENDED)) != 0) {
regerror (eval, &rp, errbuf, sizeof(errbuf));
ast_log(LOG_WARNING,"regcomp() error : %s",errbuf);
free_value(a);
free_value(b);
return make_str("");
}
/* compare string against pattern */
/* remember that patterns are anchored to the beginning of the line */
if (regexec(&rp, a->u.s, (size_t)2, rm, 0) == 0 && rm[0].rm_so == 0) {
if (rm[1].rm_so >= 0) {
*(a->u.s + rm[1].rm_eo) = '\0';
v = make_str (a->u.s + rm[1].rm_so);
} else {
v = make_integer ((quad_t)(rm[0].rm_eo - rm[0].rm_so));
}
} else {
if (rp.re_nsub == 0) {
v = make_integer ((quad_t)0);
} else {
v = make_str ("");
}
}
/* free arguments and pattern buffer */
free_value (a);
free_value (b);
regfree (&rp);
return v;
}

View File

@@ -1,32 +0,0 @@
/*
* Asterisk -- A telephony toolkit for Linux.
*
* General Definitions for Asterisk top level program
*
* Copyright (C) 1999, Mark Spencer
*
* Mark Spencer <markster@linux-support.net>
*
* This program is free software, distributed under the terms of
* the GNU General Public License
*/
#ifndef _ASTCONF_H
#define _ASTCONF_H
#define AST_CONFIG_MAX_PATH 255
extern char ast_config_AST_CONFIG_DIR[AST_CONFIG_MAX_PATH];
extern char ast_config_AST_CONFIG_FILE[AST_CONFIG_MAX_PATH];
extern char ast_config_AST_MODULE_DIR[AST_CONFIG_MAX_PATH];
extern char ast_config_AST_SPOOL_DIR[AST_CONFIG_MAX_PATH];
extern char ast_config_AST_VAR_DIR[AST_CONFIG_MAX_PATH];
extern char ast_config_AST_LOG_DIR[AST_CONFIG_MAX_PATH];
extern char ast_config_AST_AGI_DIR[AST_CONFIG_MAX_PATH];
extern char ast_config_AST_DB[AST_CONFIG_MAX_PATH];
extern char ast_config_AST_KEY_DIR[AST_CONFIG_MAX_PATH];
extern char ast_config_AST_PID[AST_CONFIG_MAX_PATH];
extern char ast_config_AST_SOCKET[AST_CONFIG_MAX_PATH];
extern char ast_config_AST_RUN_DIR[AST_CONFIG_MAX_PATH];
#endif

Binary file not shown.

1827
asterisk.c

File diff suppressed because it is too large Load Diff

View File

@@ -16,24 +16,15 @@
#define DEFAULT_LANGUAGE "en"
#define AST_CONFIG_MAX_PATH 255
#define AST_CONFIG_DIR ASTETCDIR
#define AST_RUN_DIR ASTVARRUNDIR
#define AST_SOCKET ASTVARRUNDIR "/asterisk.ctl"
#define AST_PID ASTVARRUNDIR "/asterisk.pid"
#define AST_MODULE_DIR ASTMODDIR
#define AST_SPOOL_DIR ASTSPOOLDIR
#define AST_VAR_DIR ASTVARLIBDIR
#define AST_LOG_DIR ASTLOGDIR
#define AST_AGI_DIR ASTAGIDIR
#define AST_KEY_DIR ASTVARLIBDIR "/keys"
#define AST_DB ASTVARLIBDIR "/astdb"
#define AST_TMP_DIR ASTSPOOLDIR "/tmp"
#define AST_CONFIG_DIR "/etc/asterisk"
#define AST_MODULE_DIR "/usr/lib/asterisk/modules"
#define AST_SPOOL_DIR "/var/spool/asterisk"
#define AST_VAR_DIR "/var/lib/asterisk"
#define AST_LOG_DIR "/var/log/asterisk"
#define AST_CONFIG_FILE ASTCONFPATH
#define AST_CONFIG_FILE "asterisk.conf"
#define AST_SOUNDS AST_VAR_DIR "/sounds"
#define AST_IMAGES AST_VAR_DIR "/images"
/* Provided by module.c */
extern int load_modules(void);
@@ -41,14 +32,5 @@ extern int load_modules(void);
extern int load_pbx(void);
/* Provided by logger.c */
extern int init_logger(void);
extern void close_logger(void);
/* Provided by frame.c */
extern int init_framer(void);
/* Provided by logger.c */
extern int reload_logger(int);
/* Provided by term.c */
extern int term_init(void);
/* Provided by db.c */
extern int astdb_init(void);
#endif

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