From 3f3cb2f98c9d0ee88d80be978b178e59d284fa15 Mon Sep 17 00:00:00 2001 From: russell Date: Thu, 11 Nov 2010 22:13:38 +0000 Subject: Remove most of the contents of the doc dir in favor of the wiki content. This merge does the following things: * Removes most of the contents from the doc/ directory in favor of the wiki - http://wiki.asterisk.org/ * Updates the build_tools/prep_tarball script to know how to export the contents of the wiki in both PDF and plain text formats so that the documentation is still included in Asterisk release tarballs. git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.8@294740 f38db490-d61c-443f-a65b-d21fe96a405b --- Makefile | 9 - build_tools/prep_tarball | 20 +- doc/CODING-GUIDELINES | 982 ---------------------- doc/HOWTO_collect_debug_information.txt | 89 -- doc/India-CID.txt | 75 -- doc/PEERING | 503 ------------ doc/README.txt | 10 + doc/advice_of_charge.txt | 189 ----- doc/asterisk-mib.txt | 778 ------------------ doc/backtrace.txt | 277 ------- doc/building_queues.txt | 823 ------------------- doc/callfiles.txt | 139 ---- doc/chan_sip-perf-testing.txt | 110 --- doc/cli.txt | 33 - doc/codec-64bit.txt | 47 -- doc/database_transactions.txt | 29 - doc/datastores.txt | 63 -- doc/digium-mib.txt | 24 - doc/distributed_devstate-XMPP.txt | 433 ---------- doc/distributed_devstate.txt | 320 -------- doc/externalivr.txt | 197 ----- doc/followme.txt | 32 - doc/google-soc2009-ideas.txt | 3 - doc/hoard.txt | 38 - doc/jabber.txt | 107 --- doc/janitor-projects.txt | 28 - doc/jingle.txt | 10 - doc/ldap.txt | 65 -- doc/macroexclusive.txt | 78 -- doc/manager_1_1.txt | 454 ----------- doc/modules.txt | 25 - doc/osp.txt | 747 ----------------- doc/queue.txt | 39 - doc/realtimetext.txt | 84 -- doc/res_config_sqlite.txt | 124 --- doc/rtp-packetization.txt | 75 -- doc/sip-retransmit.txt | 126 --- doc/siptls.txt | 97 --- doc/smdi.txt | 137 ---- doc/sms.txt | 147 ---- doc/snmp.txt | 53 -- doc/speechrec.txt | 295 ------- doc/ss7.txt | 116 --- doc/tex/Makefile | 76 -- doc/tex/README.txt | 24 - doc/tex/ael.tex | 1305 ------------------------------ doc/tex/ajam.tex | 97 --- doc/tex/app-sms.tex | 518 ------------ doc/tex/asterisk-conf.tex | 149 ---- doc/tex/asterisk.tex | 183 ----- doc/tex/backtrace.tex | 217 ----- doc/tex/billing.tex | 86 -- doc/tex/calendaring.tex | 206 ----- doc/tex/ccss.tex | 414 ---------- doc/tex/cdrdriver.tex | 509 ------------ doc/tex/cel-doc.tex | 958 ---------------------- doc/tex/celdriver.tex | 451 ----------- doc/tex/chan-mobile.tex | 262 ------ doc/tex/chaniax.tex | 84 -- doc/tex/channelvariables.tex | 1066 ------------------------ doc/tex/cliprompt.tex | 29 - doc/tex/configuration.tex | 233 ------ doc/tex/dundi.tex | 41 - doc/tex/enum.tex | 355 -------- doc/tex/extensions.tex | 79 -- doc/tex/freetds.tex | 6 - doc/tex/hardware.tex | 100 --- doc/tex/ices.tex | 7 - doc/tex/imapstorage.tex | 241 ------ doc/tex/jitterbuffer.tex | 98 --- doc/tex/localchannel.tex | 508 ------------ doc/tex/manager.tex | 274 ------- doc/tex/misdn.tex | 282 ------- doc/tex/mp3.tex | 11 - doc/tex/odbcstorage.tex | 34 - doc/tex/partymanip.tex | 331 -------- doc/tex/phoneprov.tex | 307 ------- doc/tex/plc.tex | 139 ---- doc/tex/privacy.tex | 364 --------- doc/tex/qos.tex | 144 ---- doc/tex/queuelog.tex | 118 --- doc/tex/queues-with-callback-members.tex | 551 ------------- doc/tex/realtime.tex | 150 ---- doc/tex/secure-calls.tex | 45 -- doc/tex/security-events.tex | 250 ------ doc/tex/security.tex | 80 -- doc/tex/sla.tex | 387 --------- doc/tex/sounds.tex | 80 -- doc/timing.txt | 90 --- doc/unistim.txt | 127 --- doc/valgrind.txt | 24 - doc/video.txt | 47 -- doc/video_console.txt | 159 ---- doc/voicemail_odbc_postgresql.txt | 454 ----------- 94 files changed, 15 insertions(+), 20765 deletions(-) delete mode 100644 doc/CODING-GUIDELINES delete mode 100644 doc/HOWTO_collect_debug_information.txt delete mode 100644 doc/India-CID.txt delete mode 100644 doc/PEERING create mode 100644 doc/README.txt delete mode 100644 doc/advice_of_charge.txt delete mode 100644 doc/asterisk-mib.txt delete mode 100644 doc/backtrace.txt delete mode 100644 doc/building_queues.txt delete mode 100644 doc/callfiles.txt delete mode 100644 doc/chan_sip-perf-testing.txt delete mode 100644 doc/cli.txt delete mode 100644 doc/codec-64bit.txt delete mode 100644 doc/database_transactions.txt delete mode 100644 doc/datastores.txt delete mode 100644 doc/digium-mib.txt delete mode 100644 doc/distributed_devstate-XMPP.txt delete mode 100644 doc/distributed_devstate.txt delete mode 100644 doc/externalivr.txt delete mode 100644 doc/followme.txt delete mode 100644 doc/google-soc2009-ideas.txt delete mode 100644 doc/hoard.txt delete mode 100644 doc/jabber.txt delete mode 100644 doc/janitor-projects.txt delete mode 100644 doc/jingle.txt delete mode 100644 doc/ldap.txt delete mode 100644 doc/macroexclusive.txt delete mode 100644 doc/manager_1_1.txt delete mode 100644 doc/modules.txt delete mode 100644 doc/osp.txt delete mode 100644 doc/queue.txt delete mode 100644 doc/realtimetext.txt delete mode 100644 doc/res_config_sqlite.txt delete mode 100644 doc/rtp-packetization.txt delete mode 100644 doc/sip-retransmit.txt delete mode 100644 doc/siptls.txt delete mode 100644 doc/smdi.txt delete mode 100644 doc/sms.txt delete mode 100644 doc/snmp.txt delete mode 100644 doc/speechrec.txt delete mode 100644 doc/ss7.txt delete mode 100644 doc/tex/Makefile delete mode 100644 doc/tex/README.txt delete mode 100644 doc/tex/ael.tex delete mode 100644 doc/tex/ajam.tex delete mode 100644 doc/tex/app-sms.tex delete mode 100644 doc/tex/asterisk-conf.tex delete mode 100644 doc/tex/asterisk.tex delete mode 100644 doc/tex/backtrace.tex delete mode 100644 doc/tex/billing.tex delete mode 100644 doc/tex/calendaring.tex delete mode 100644 doc/tex/ccss.tex delete mode 100644 doc/tex/cdrdriver.tex delete mode 100644 doc/tex/cel-doc.tex delete mode 100644 doc/tex/celdriver.tex delete mode 100644 doc/tex/chan-mobile.tex delete mode 100644 doc/tex/chaniax.tex delete mode 100644 doc/tex/channelvariables.tex delete mode 100644 doc/tex/cliprompt.tex delete mode 100644 doc/tex/configuration.tex delete mode 100644 doc/tex/dundi.tex delete mode 100644 doc/tex/enum.tex delete mode 100644 doc/tex/extensions.tex delete mode 100644 doc/tex/freetds.tex delete mode 100644 doc/tex/hardware.tex delete mode 100644 doc/tex/ices.tex delete mode 100644 doc/tex/imapstorage.tex delete mode 100644 doc/tex/jitterbuffer.tex delete mode 100644 doc/tex/localchannel.tex delete mode 100644 doc/tex/manager.tex delete mode 100644 doc/tex/misdn.tex delete mode 100644 doc/tex/mp3.tex delete mode 100644 doc/tex/odbcstorage.tex delete mode 100644 doc/tex/partymanip.tex delete mode 100644 doc/tex/phoneprov.tex delete mode 100644 doc/tex/plc.tex delete mode 100644 doc/tex/privacy.tex delete mode 100644 doc/tex/qos.tex delete mode 100644 doc/tex/queuelog.tex delete mode 100644 doc/tex/queues-with-callback-members.tex delete mode 100644 doc/tex/realtime.tex delete mode 100644 doc/tex/secure-calls.tex delete mode 100644 doc/tex/security-events.tex delete mode 100644 doc/tex/security.tex delete mode 100644 doc/tex/sla.tex delete mode 100644 doc/tex/sounds.tex delete mode 100644 doc/timing.txt delete mode 100644 doc/unistim.txt delete mode 100644 doc/valgrind.txt delete mode 100644 doc/video.txt delete mode 100644 doc/video_console.txt delete mode 100644 doc/voicemail_odbc_postgresql.txt diff --git a/Makefile b/Makefile index 61be67f40..976d5b885 100644 --- a/Makefile +++ b/Makefile @@ -922,14 +922,6 @@ menuselect-tree: $(foreach dir,$(filter-out main,$(MOD_SUBDIRS)),$(wildcard $(di @cat sounds/sounds.xml >> $@ @echo "" >> $@ -pdf: asterisk.pdf -asterisk.pdf: - $(MAKE) -C doc/tex asterisk.pdf - -txt: asterisk.txt -asterisk.txt: - $(MAKE) -C doc/tex asterisk.txt - .PHONY: menuselect .PHONY: main .PHONY: sounds @@ -942,7 +934,6 @@ asterisk.txt: .PHONY: uninstall .PHONY: _uninstall .PHONY: uninstall-all -.PHONY: pdf .PHONY: dont-optimize .PHONY: badshell .PHONY: installdirs diff --git a/build_tools/prep_tarball b/build_tools/prep_tarball index 6fe06c427..e101c5d03 100755 --- a/build_tools/prep_tarball +++ b/build_tools/prep_tarball @@ -8,18 +8,8 @@ make -C sounds MENUSELECT_CORE_SOUNDS=CORE-SOUNDS-EN-GSM MENUSELECT_MOH=MOH-OPSOUND-WAV WGET=wget DOWNLOAD=wget all make AWK=awk GREP=grep menuselect-tree -make_tex_docs() { - # make backup of asterisk.tex because we are going to alter it - cp asterisk.tex asterisk.tex.orig - sed -e "s/ASTERISKVERSION/${VERSION}/" asterisk.tex > asterisk_local.tex - mv asterisk_local.tex asterisk.tex - rubber --pdf asterisk.tex - latex2html asterisk.tex - latex asterisk.tex - catdvi -e 1 -U asterisk.dvi | sed -re "s/\[U\+2022\]/*/g" | sed -re "s/\[U\+02C6\]/^/g" | sed -re "s/([^^[:space:]])\s+/\1 /g" > asterisk.txt - # restore backup of asterisk.tex - mv asterisk.tex.orig asterisk.tex -} - -VERSION=`cat .version` -cd doc/tex && make_tex_docs +cd doc +echo "Exporting Asterisk wiki to a PDF (this will take a minute) ..." +wikiexport.py +echo "Converting wiki export PDF to plain text ..." +pdftotext AST.pdf diff --git a/doc/CODING-GUIDELINES b/doc/CODING-GUIDELINES deleted file mode 100644 index d1ae32dfe..000000000 --- a/doc/CODING-GUIDELINES +++ /dev/null @@ -1,982 +0,0 @@ - -------------------------------------- - == Asterisk Coding Guidelines == - -------------------------------------- - -This document gives some basic indication on how the asterisk code -is structured. The first part covers the structure and style of -individual files. The second part (TO BE COMPLETED) covers the -overall code structure and the build architecture. - -Please read it to the end to understand in detail how the asterisk -code is organized, and to know how to extend asterisk or contribute -new code. - -We are looking forward to your contributions to Asterisk - the -Open Source PBX! As Asterisk is a large and in some parts very -time-sensitive application, the code base needs to conform to -a common set of coding rules so that many developers can enhance -and maintain the code. Code also needs to be reviewed and tested -so that it works and follows the general architecture and guide- -lines, and is well documented. - -Asterisk is published under a dual-licensing scheme by Digium. -To be accepted into the codebase, all non-trivial changes must be -licensed to Digium. For more information, see the electronic license -agreement on https://issues.asterisk.org/. - -Patches should be in the form of a unified (-u) diff, made from a checkout -from subversion. - -/usr/src/asterisk$ svn diff > mypatch - -If you would like to only include changes to certain files in the patch, you -can list them in the "svn diff" command: - -/usr/src/asterisk$ svn diff somefile.c someotherfile.c > mypatch - - ----------------------------------- - == PART ONE: CODING GUIDELINES == - ----------------------------------- - -* General rules ---------------- - -- Indent code using tabs, not spaces. - -- All code, filenames, function names and comments must be in ENGLISH. - -- Don't annotate your changes with comments like "/* JMG 4/20/04 */"; - Comments should explain what the code does, not when something was changed - or who changed it. If you have done a larger contribution, make sure - that you are added to the CREDITS file. - -- Don't make unnecessary whitespace changes throughout the code. - If you make changes, submit them to the tracker as separate patches - that only include whitespace and formatting changes. - -- Don't use C++ type (//) comments. - -- Try to match the existing formatting of the file you are working on. - -- Use spaces instead of tabs when aligning in-line comments or #defines (this makes - your comments aligned even if the code is viewed with another tabsize) - -* File structure and header inclusion -------------------------------------- - -Every C source file should start with a proper copyright -and a brief description of the content of the file. -Following that, you should immediately put the following lines: - -#include "asterisk.h" -ASTERISK_FILE_VERSION(__FILE__, "$Revision$") - -"asterisk.h" resolves OS and compiler dependencies for the basic -set of unix functions (data types, system calls, basic I/O -libraries) and the basic Asterisk APIs. -ASTERISK_FILE_VERSION() stores in the executable information -about the file. - -Next, you should #include extra headers according to the functionality -that your file uses or implements. For each group of functions that -you use there is a common header, which covers OS header dependencies -and defines the 'external' API of those functions (the equivalent -of 'public' members of a class). As an example: - - asterisk/module.h - if you are implementing a module, this should be included in one - of the files that are linked with the module. - - asterisk/io.h - access to extra file I/O functions (stat, fstat, playing with - directories etc) - - asterisk/network.h - basic network I/O - all of the socket library, select/poll, - and asterisk-specific (usually either thread-safe or reentrant - or both) functions to play with socket addresses. - - asterisk/app.h - parsing of application arguments - - asterisk/channel.h - struct ast_channel and functions to manipulate it - -For more information look at the headers in include/asterisk/ . -These files are usually self-sufficient, i.e. they recursively #include -all the extra headers they need. - -The equivalent of 'private' members of a class are either directly in -the C source file, or in files named asterisk/mod_*.h to make it clear -that they are not for inclusion by generic code. - -Keep the number of header files small by not including them unnecessarily. -Don't cut&paste list of header files from other sources, but only include -those you really need. Apart from obvious cases (e.g. module.h which -is almost always necessary) write a short comment next to each #include to -explain why you need it. - -* Declaration of functions and variables ----------------------------------------- - -- Do not declare variables mid-block (e.g. like recent GNU compilers support) - since it is harder to read and not portable to GCC 2.95 and others. - -- Functions and variables that are not intended to be used outside the module - must be declared static. If you are compiling on a Linux platform that has the - 'dwarves' package available, you can use the 'pglobal' tool from that package - to check for unintended global variables or functions being exposed in your - object files. Usage is very simple: - - $ pglobal -vf - -- When reading integer numeric input with scanf (or variants), do _NOT_ use '%i' - unless you specifically want to allow non-base-10 input; '%d' is always a better - choice, since it will not silently turn numbers with leading zeros into base-8. - -- Strings that are coming from input should not be used as the format argument to - any printf-style function. - -* Structure alignment and padding ---------------------------------- - -On many platforms, structure fields (in structures that are not marked 'packed') -will be laid out by the compiler with gaps (padding) between them, in order to -satisfy alignment requirements. As a simple example: - -struct foo { - int bar; - void *xyz; -} - -On nearly every 64-bit platform, this will result in 4 bytes of dead space between -'bar' and 'xyz', because pointers on 64-bit platforms must be aligned on 8-byte -boundaries. Once you have your code written and tested, it may be worthwhile to review -your structure definitions to look for problems of this nature. If you are on a Linux -platform with the 'dwarves' package available, the 'pahole' tool from that package -can be used to both check for padding issues of this type and also propose reorganized -structure definitions to eliminate it. Usage is quite simple; for a structure named 'foo', -the command would look something like this: - -$ pahole --reorganize --show_reorg_steps -C foo - -The 'pahole' tool has many other modes available, including some that will list all the -structures declared in the module and the amount of padding in each one that could possibly -be recovered. - -* Use the internal API ----------------------- - -- Make sure you are aware of the string and data handling functions that exist - within Asterisk to enhance portability and in some cases to produce more - secure and thread-safe code. Check utils.c/utils.h for these. - -- If you need to create a detached thread, use the ast_pthread_create_detached() - normally or ast_pthread_create_detached_background() for a thread with a smaller - stack size. This reduces the replication of the code to handle the pthread_attr_t - structure. - -* Code formatting ------------------ - -Roughly, Asterisk code formatting guidelines are generally equivalent to the -following: - -# indent -i4 -ts4 -br -brs -cdw -lp -ce -nbfda -npcs -nprs -npsl -nbbo -saf -sai -saw -cs -l90 foo.c - -this means in verbose: - -i4: indent level 4 - -ts4: tab size 4 - -br: braces on if line - -brs: braces on struct decl line - -cdw: cuddle do while - -lp: line up continuation below parenthesis - -ce: cuddle else - -nbfda: dont break function decl args - -npcs: no space after function call names - -nprs: no space after parentheses - -npsl: dont break procedure type - -saf: space after for - -sai: space after if - -saw: space after while - -cs: space after cast - -l90: line length 90 columns - -Function calls and arguments should be spaced in a consistent way across -the codebase. - GOOD: foo(arg1, arg2); - BAD: foo(arg1,arg2); - BAD: foo (arg1, arg2); - BAD: foo( arg1, arg2 ); - BAD: foo(arg1, arg2,arg3); - -Don't treat keywords (if, while, do, return) as if they were functions; -leave space between the keyword and the expression used (if any). For 'return', -don't even put parentheses around the expression, since they are not -required. - -There is no shortage of whitespace characters :-) Use them when they make -the code easier to read. For example: - - for (str=foo;str;str=str->next) - -is harder to read than - - for (str = foo; str; str = str->next) - -Following are examples of how code should be formatted. - -- Functions: -int foo(int a, char *s) -{ - return 0; -} - -- If statements: -if (foo) { - bar(); -} else { - blah(); -} - -- Case statements: -switch (foo) { -case BAR: - blah(); - break; -case OTHER: - other(); - break; -} - -- No nested statements without braces, e.g.: - -for (x = 0; x < 5; x++) - if (foo) - if (bar) - baz(); - -instead do: -for (x = 0; x < 5; x++) { - if (foo) { - if (bar) { - baz(); - } - } -} - -- Always use braces around the statements following an if/for/while construct, -even if not strictly necessary, as it reduces future possible problems. - -- Don't build code like this: - -if (foo) { - /* .... 50 lines of code ... */ -} else { - result = 0; - return; -} - -Instead, try to minimize the number of lines of code that need to be -indented, by only indenting the shortest case of the 'if' -statement, like so: - -if (!foo) { - result = 0; - return; -} - -.... 50 lines of code .... - -When this technique is used properly, it makes functions much easier to read -and follow, especially those with more than one or two 'setup' operations -that must succeed for the rest of the function to be able to execute. - -- Labels/goto are acceptable -Proper use of this technique may occasionally result in the need for a -label/goto combination so that error/failure conditions can exit the -function while still performing proper cleanup. This is not a bad thing! -Use of goto in this situation is encouraged, since it removes the need -for excess code indenting without requiring duplication of cleanup code. - -- Never use an uninitialized variable -Make sure you never use an uninitialized variable. The compiler will -usually warn you if you do so. However, do not go too far the other way, -and needlessly initialize variables that do not require it. If the first -time you use a variable in a function is to store a value there, then -initializing it at declaration is pointless, and will generate extra -object code and data in the resulting binary with no purpose. When in doubt, -trust the compiler to tell you when you need to initialize a variable; -if it does not warn you, initialization is not needed. - -- Do not cast 'void *' -Do not explicitly cast 'void *' into any other type, nor should you cast any -other type into 'void *'. Implicit casts to/from 'void *' are explicitly -allowed by the C specification. This means the results of malloc(), calloc(), -alloca(), and similar functions do not _ever_ need to be cast to a specific -type, and when you are passing a pointer to (for example) a callback function -that accepts a 'void *' you do not need to cast into that type. - -* Function naming ------------------ - -All public functions (those not marked 'static'), must be named "ast_" -and have a descriptive name. - -As an example, suppose you wanted to take a local function "find_feature", defined -as static in a file, and used only in that file, and make it public, and use it -in other files. You will have to remove the "static" declaration and define a -prototype in an appropriate header file (usually in include/asterisk). A more -specific name should be given, such as "ast_find_call_feature". - -* Variable function argument parsing ------------------------------------- - -Functions with a variable amount of arguments need a 'sentinel' when called. -Newer GNU C compilers are fine if you use NULL for this. Older versions (pre 4) -don't like this. -You should use the constant SENTINEL. -This one is defined in include/asterisk/compiler.h - -* Variable naming ------------------ - -- Global variables -Name global variables (or local variables when you have a lot of them or -are in a long function) something that will make sense to aliens who -find your code in 100 years. All variable names should be in lower -case, except when following external APIs or specifications that normally -use upper- or mixed-case variable names; in that situation, it is -preferable to follow the external API/specification for ease of -understanding. - -Make some indication in the name of global variables which represent -options that they are in fact intended to be global. - e.g.: static char global_something[80] - -- Don't use unnecessary typedef's -Don't use 'typedef' just to shorten the amount of typing; there is no substantial -benefit in this: -struct foo { int bar; }; typedef struct foo foo_t; - -In fact, don't use 'variable type' suffixes at all; it's much preferable to -just type 'struct foo' rather than 'foo_s'. - -- Use enums instead of #define where possible -Use enums rather than long lists of #define-d numeric constants when possible; -this allows structure members, local variables and function arguments to -be declared as using the enum's type. For example: - -enum option { - OPT_FOO = 1, - OPT_BAR = 2, - OPT_BAZ = 4, -}; - -static enum option global_option; - -static handle_option(const enum option opt) -{ - ... -} - -Note: The compiler will _not_ force you to pass an entry from the enum -as an argument to this function; this recommendation serves only to make -the code clearer and somewhat self-documenting. In addition, when using -switch/case blocks that switch on enum values, the compiler will warn -you if you forget to handle one or more of the enum values, which can be -handy. - -* String handling ------------------ - -Don't use strncpy for copying whole strings; it does not guarantee that the -output buffer will be null-terminated. Use ast_copy_string instead, which -is also slightly more efficient (and allows passing the actual buffer -size, which makes the code clearer). - -Don't use ast_copy_string (or any length-limited copy function) for copying -fixed (known at compile time) strings into buffers, if the buffer is something -that has been allocated in the function doing the copying. In that case, you -know at the time you are writing the code whether the buffer is large enough -for the fixed string or not, and if it's not, your code won't work anyway! -Use strcpy() for this operation, or directly set the first two characters -of the buffer if you are just trying to store a one character string in the -buffer. If you are trying to 'empty' the buffer, just store a single -NULL character ('\0') in the first byte of the buffer; nothing else is -needed, and any other method is wasteful. - -In addition, if the previous operations in the function have already -determined that the buffer in use is adequately sized to hold the string -you wish to put into it (even if you did not allocate the buffer yourself), -use a direct strcpy(), as it can be inlined and optimized to simple -processor operations, unlike ast_copy_string(). - -* String conversions --------------------- - -When converting from strings to integers or floats, use the sscanf function -in preference to the atoi and atof family of functions, as sscanf detects -errors. Always check the return value of sscanf to verify that your numeric -variables successfully scanned before using them. Also, to avoid a potential -libc bug, always specify a maximum width for each conversion specifier, -including integers and floats. A good length for both integers and floats is -30, as this is more than generous, even if you're using doubles or long -integers. - -* Use of functions ------------------- - -For the sake of uclibc, do not use index, bcopy or bzero; use strchr(), memset(), -and memmove() instead. uclibc can be configured to supply these functions, but -we can save these users time and consternation if we abstain from using these -functions. - -When making applications, always ast_strdupa(data) to a local pointer if you -intend to parse the incoming data string. - - if (data) { - mydata = ast_strdupa(data); - } - -- Use the argument parsing macros to declare arguments and parse them, i.e.: - - AST_DECLARE_APP_ARGS(args, - AST_APP_ARG(arg1); - AST_APP_ARG(arg2); - AST_APP_ARG(arg3); - ); - parse = ast_strdupa(data); - AST_STANDARD_APP_ARGS(args, parse); - -- Create generic code! -If you do the same or a similar operation more than one time, make it a -function or macro. - -Make sure you are not duplicating any functionality already found in an -API call somewhere. If you are duplicating functionality found in -another static function, consider the value of creating a new API call -which can be shared. - -* Handling of pointers and allocations --------------------------------------- - -- Dereference or localize pointers -Always dereference or localize pointers to things that are not yours like -channel members in a channel that is not associated with the current -thread and for which you do not have a lock. - channame = ast_strdupa(otherchan->name); - -- Use const on pointer arguments if possible -Use const on pointer arguments which your function will not be modifying, as this -allows the compiler to make certain optimizations. In general, use 'const' -on any argument that you have no direct intention of modifying, as it can -catch logic/typing errors in your code when you use the argument variable -in a way that you did not intend. - -- Do not create your own linked list code - reuse! -As a common example of this point, make an effort to use the lockable -linked-list macros found in include/asterisk/linkedlists.h. They are -efficient, easy to use and provide every operation that should be -necessary for managing a singly-linked list (if something is missing, -let us know!). Just because you see other open-coded list implementations -in the source tree is no reason to continue making new copies of -that code... There are also a number of common string manipulation -and timeval manipulation functions in asterisk/strings.h and asterisk/time.h; -use them when possible. - -- Avoid needless allocations! -Avoid needless malloc(), strdup() calls. If you only need the value in -the scope of your function try ast_strdupa() or declare structs on the -stack and pass a pointer to them. However, be careful to _never_ call -alloca(), ast_strdupa() or similar functions in the argument list -of a function you are calling; this can cause very strange stack -arrangements and produce unexpected behavior. - -- Allocations for structures -When allocating/zeroing memory for a structure, use code like this: - -struct foo *tmp; - -... - -tmp = ast_calloc(1, sizeof(*tmp)); - -Avoid the combination of ast_malloc() and memset(). Instead, always use -ast_calloc(). This will allocate and zero the memory in a single operation. -In the case that uninitialized memory is acceptable, there should be a comment -in the code that states why this is the case. - -Using sizeof(*tmp) instead of sizeof(struct foo) eliminates duplication of the -'struct foo' identifier, which makes the code easier to read and also ensures -that if it is copy-and-pasted it won't require as much editing. - -The ast_* family of functions for memory allocation are functionally the same. -They just add an Asterisk log error message in the case that the allocation -fails for some reason. This eliminates the need to generate custom messages -throughout the code to log that this has occurred. - -- String Duplications - -The functions strdup and strndup can *not* accept a NULL argument. This results -in having code like this: - - if (str) { - newstr = strdup(str); - } else { - newstr = NULL; - } - -However, the ast_strdup and ast_strdupa functions will happily accept a NULL -argument without generating an error. The same code can be written as: - - newstr = ast_strdup(str); - -Furthermore, it is unnecessary to have code that malloc/calloc's for the length -of a string (+1 for the terminating '\0') and then using strncpy to copy the -copy the string into the resulting buffer. This is the exact same thing as -using ast_strdup. - -* CLI Commands --------------- - -New CLI commands should be named using the module's name, followed by a verb -and then any parameters that the command needs. For example: - -*CLI> iax2 show peer - -not - -*CLI> show iax2 peer - -* New dialplan applications/functions -------------------------------------- - -There are two methods of adding functionality to the Asterisk -dialplan: applications and functions. Applications (found generally in -the apps/ directory) should be collections of code that interact with -a channel and/or user in some significant way. Functions (which can be -provided by any type of module) are used when the provided -functionality is simple... getting/retrieving a value, for -example. Functions should also be used when the operation is in no way -related to a channel (a computation or string operation, for example). - -Applications are registered and invoked using the -ast_register_application function; see the apps/app_skel.c file for an -example. - -Functions are registered using 'struct ast_custom_function' -structures and the ast_custom_function_register function. - -* Doxygen API Documentation Guidelines --------------------------------------- - -When writing Asterisk API documentation the following format should be -followed. Do not use the javadoc style. - -/*! - * \brief Do interesting stuff. - * - * \param thing1 interesting parameter 1. - * \param thing2 interesting parameter 2. - * - * This function does some interesting stuff. - * - * \retval zero on success - * \retval -1 on error. - */ -int ast_interesting_stuff(int thing1, int thing2) -{ - return 0; -} - -Notice the use of the \param, \brief, and \return constructs. These should be -used to describe the corresponding pieces of the function being documented. -Also notice the blank line after the last \param directive. All doxygen -comments must be in one /*! */ block. If the function or struct does not need -an extended description it can be left out. - -Please make sure to review the doxygen manual and make liberal use of the \a, -\code, \c, \b, \note, \li and \e modifiers as appropriate. - -When documenting a 'static' function or an internal structure in a module, -use the \internal modifier to ensure that the resulting documentation -explicitly says 'for internal use only'. - -When adding new API you should also attach a \since note because this will -indicate to developers that this API did not exist before this version. It -also has the benefit of making the resulting HTML documentation to group -the changes for a single version. - -Structures should be documented as follows. - -/*! - * \brief A very interesting structure. - */ -struct interesting_struct -{ - /*! \brief A data member. */ - int member1; - - int member2; /*!< \brief Another data member. */ -} - -Note that /*! */ blocks document the construct immediately following them -unless they are written, /*!< */, in which case they document the construct -preceding them. - -It is very much preferred that documentation is not done inline, as done in -the previous example for member2. The first reason for this is that it tends -to encourage extremely brief, and often pointless, documentation since people -try to keep the comment from making the line extremely long. However, if you -insist on using inline comments, please indent the documentation with spaces! -That way, all of the comments are properly aligned, regardless of what tab -size is being used for viewing the code. - -* Finishing up before you submit your code ------------------------------------------- - -- Look at the code once more -When you achieve your desired functionality, make another few refactor -passes over the code to optimize it. - -- Read the patch -Before submitting a patch, *read* the actual patch file to be sure that -all the changes you expect to be there are, and that there are no -surprising changes you did not expect. During your development, that -part of Asterisk may have changed, so make sure you compare with the -latest SVN. - -- Listen to advice -If you are asked to make changes to your patch, there is a good chance -the changes will introduce bugs, check it even more at this stage. -Also remember that the bug marshal or co-developer that adds comments -is only human, they may be in error :-) - -- Optimize, optimize, optimize -If you are going to reuse a computed value, save it in a variable -instead of recomputing it over and over. This can prevent you from -making a mistake in subsequent computations, making it easier to correct -if the formula has an error and may or may not help optimization but -will at least help readability. - -Just an example (so don't over analyze it, that'd be a shame): - -const char *prefix = "pre"; -const char *postfix = "post"; -char *newname; -char *name = "data"; - -if (name && (newname = alloca(strlen(name) + strlen(prefix) + strlen(postfix) + 3))) { - snprintf(newname, strlen(name) + strlen(prefix) + strlen(postfix) + 3, "%s/%s/%s", prefix, name, postfix); -| - -...vs this alternative: - -const char *prefix = "pre"; -const char *postfix = "post"; -char *newname; -char *name = "data"; -int len = 0; - -if (name && (len = strlen(name) + strlen(prefix) + strlen(postfix) + 3) && (newname = alloca(len))) { - snprintf(newname, len, "%s/%s/%s", prefix, name, postfix); -} - -* Creating new manager events? ------------------------------- -If you create new AMI events, please read manager.txt. Do not re-use -existing headers for new purposes, but please re-use existing headers -for the same type of data. - -Manager events that signal a status are required to have one -event name, with a status header that shows the status. -The old style, with one event named "ThisEventOn" and another named -"ThisEventOff", is no longer approved. - -Check manager.txt for more information on manager and existing -headers. Please update this file if you add new headers. - -* Locking in Asterisk ------------------------------ - -A) Locking Fundamentals - -Asterisk is a heavily multithreaded application. It makes extensive -use of locking to ensure safe access to shared resources between -different threads. - -When more that one lock is involved in a given code path, there is the -potential for deadlocks. A deadlock occurs when a thread is stuck -waiting for a resource that it will never acquire. Here is a classic -example of a deadlock: - - Thread 1 Thread 2 - ------------ ------------ - Holds Lock A Holds Lock B - Waiting for Lock B Waiting for Lock A - -In this case, there is a deadlock between threads 1 and 2. -This deadlock would have been avoided if both threads had -agreed that one must acquire Lock A before Lock B. - -In general, the fundamental rule for dealing with multiple locks is - - an order _must_ be established to acquire locks, and then all threads - must respect that order when acquiring locks. - - -A.1) Establishing a locking order - -Because any ordering for acquiring locks is ok, one could establish -the rule arbitrarily, e.g. ordering by address, or by some other criterion. -The main issue, though, is defining an order that - i) is easy to check at runtime; - ii) reflects the order in which the code executes. -As an example, if a data structure B is only accessible through a -data structure A, and both require locking, then the natural order -is locking first A and then B. -As another example, if we have some unrelated data structures to -be locked in pairs, then a possible order can be based on the address -of the data structures themselves. - -B) Minding the boundary between channel drivers and the Asterisk core - -The #1 cause of deadlocks in Asterisk is by not properly following the -locking rules that exist at the boundary between Channel Drivers and -the Asterisk core. The Asterisk core allocates an ast_channel, and -Channel Drivers allocate "technology specific private data" (PVT) that is -associated with an ast_channel. Typically, both the ast_channel and -PVT have their own lock. There are _many_ -code paths that require both objects to be locked. - -The locking order in this situation is the following: - - 1) ast_channel - 2) PVT - -Channel Drivers implement the ast_channel_tech interface to provide a -channel implementation for Asterisk. Most of the channel_tech -interface callbacks are called with the associated ast_channel -locked. When accessing technology specific data, the PVT can be locked -directly because the locking order is respected. - -C) Preventing lock ordering reversals. - -There are some code paths which make it extremely difficult to -respect the locking order. -Consider for example the following situation: - - 1) A message comes in over the "network" - 2) The Channel Driver (CD) monitor thread receives the message - 3) The CD associates the message with a PVT and locks the PVT - 4) While processing the message, the CD must do something that requires - locking the ast_channel associated to the PVT - -This is the point that must be handled carefully. -The following psuedo-code - - unlock(pvt); - lock(ast_channel); - lock(pvt); - -is _not_ correct for two reasons: - -i) first and foremost, unlocking the PVT means that other threads - can acquire the lock and believe it is safe to modify the - associated data. When reacquiring the lock, the original thread - might find unexpected changes in the protected data structures. - This essentially means that the original thread must behave as if - the lock on the pvt was not held, in which case it could have - released it itself altogether; - -ii) Asterisk uses the so called "recursive" locks, which allow a thread - to issue a lock() call multiple times on the same lock. Recursive - locks count the number of calls, and they require an equivalent - number of unlock() to be actually released. - - For this reason, just calling unlock() once does not guarantee that the - lock is actually released -- it all depends on how many times lock() - was called before. - -An alternative, but still incorrect, construct is widely used in -the asterisk code to try and improve the situation: - - while (trylock(ast_channel) == FAILURE) { - unlock(pvt); - usleep(1); /* yield to other threads */ - lock(pvt); - } - -Here the trylock() is non blocking, so we do not deadlock if the ast_channel -is already locked by someone else: in this case, we try to unlock the PVT -(which happens only if the PVT lock counter is 1), yield the CPU to -give other threads a chance to run, and then acquire the lock again. - -This code is not correct for two reasons: - i) same as in the previous example, it releases the lock when the thread - probably did not expect it; - ii) if the PVT lock counter is greater than 1 we will not - really release the lock on the PVT. We might be lucky and have the - other contender actually release the lock itself, and so we will "win" - the race, but if both contenders have their lock counts > 1 then - they will loop forever (basically replacing deadlock with livelock). - -Another variant of this code is the following: - - if (trylock(ast_channel) == FAILURE) { - unlock(pvt); - lock(ast_channel); - lock(pvt); - } - -which has the same issues as the while(trylock...) code, but just -deadlocks instead of looping forever in case of lock counts > 1. - -The deadlock/livelock could be in principle spared if one had an -unlock_all() function that calls unlock as many times as needed to -actually release the lock, and reports the count. Then we could do: - - if (trylock(ast_channel) == FAILURE) { - n = unlock_all(pvt); - lock(ast_channel) - while (n-- > 0) lock(pvt); - } - -The issue with unexpected unlocks remains, though. - -C) Locking multiple channels. - -The next situation to consider is what to do when you need a lock on -multiple ast_channels (or multiple unrelated data structures). - -If we are sure that we do not hold any of these locks, then the -following construct is sufficient: - - lock(MIN(chan1, chan2)); - lock(MAX(chan1, chan2)); - -That type of code would follow an established locking order of always -locking the channel that has a lower address first. Also keep in mind -that to use this construct for channel locking, one would have to go -through the entire codebase to ensure that when two channels are locked, -this locking order is used. - However, if we enter the above section of code with some lock held -(which would be incorrect using non-recursive locks, but is completely -legal using recursive mutexes) then the locking order is not guaranteed -anymore because it depends on which locks we already hold. So we have -to go through the same tricks used for the channel+PVT case. - -D) Recommendations - -As you can see from the above discussion, getting locking right is all -but easy. So please follow these recommendations when using locks: - -*) Use locks only when really necessary - Please try to use locks only when strictly necessary, and only for - the minimum amount of time required to run critical sections of code. - A common use of locks in the current code is to protect a data structure - from being released while you use it. - With the use of reference-counted objects (astobj2) this should not be - necessary anymore. - -*) Do not sleep while holding a lock - If possible, do not run any blocking code while holding a lock, - because you will also block other threads trying to access the same - lock. In many cases, you can hold a reference to the object to avoid - that it is deleted while you sleep, perhaps set a flag in the object - itself to report other threads that you have some pending work to - complete, then release and acquire the lock around the blocking path, - checking the status of the object after you acquire the lock to make - sure that you can still perform the operation you wanted to. - -*) Try not to exploit the 'recursive' feature of locks. - Recursive locks are very convenient when coding, as you don't have to - worry, when entering a section of code, whether or not you already - hold the lock -- you can just protect the section with a lock/unlock - pair and let the lock counter track things for you. - But as you have seen, exploiting the features of recursive locks - make it a lot harder to implement proper deadlock avoidance strategies. - So please try to analyse your code and determine statically whether you - already hold a lock when entering a section of code. - If you need to call some function foo() with and without a lock held, - you could define two function as below: - foo_locked(...) { - ... do something, assume lock held - } - - foo(...) { - lock(xyz) - ret = foo_locked(...) - unlock(xyz) - return ret; - } - and call them according to the needs. - -*) Document locking rules. - Please document the locking order rules are documented for every - lock introduced into Asterisk. This is done almost nowhere in the - existing code. However, it will be expected to be there for newly - introduced code. Over time, this information should be added for - all of the existing lock usage. - ------------------------------------------------------------------------ - - - ------------------------------------ - == PART TWO: BUILD ARCHITECTURE == - ------------------------------------ - -The asterisk build architecture relies on autoconf to detect the -system configuration, and on a locally developed tool (menuselect) to -select build options and modules list, and on gmake to do the build. - -The first step, usually to be done soon after a checkout, is running -"./configure", which will store its findings in two files: - - + include/asterisk/autoconfig.h - contains C macros, normally #define HAVE_FOO or HAVE_FOO_H , - for all functions and headers that have been detected at build time. - These are meant to be used by C or C++ source files. - - + makeopts - contains variables that can be used by Makefiles. - In addition to the usual CC, LD, ... variables pointing to - the various build tools, and prefix, includedir ... which are - useful for generic compiler flags, there are variables - for each package detected. - These are normally of the form FOO_INCLUDE=... FOO_LIB=... - FOO_DIR=... indicating, for each package, the useful libraries - and header files. - -The next step is to run "make menuselect", to extract the dependencies existing -between files and modules, and to store build options. -menuselect produces two files, both to be read by the Makefile: - - + menuselect.makeopts - Contains for each subdirectory a list of modules that must be - excluded from the build, plus some additional informatiom. - + menuselect.makedeps - Contains, for each module, a list of packages it depends on. - For each of these packages, we can collect the relevant INCLUDE - and LIB files from makeopts. This file is based on information - in the .c source code files for each module. - -The top level Makefile is in charge of setting up the build environment, -creating header files with build options, and recursively invoking the -subdir Makefiles to produce modules and the main executable. - -The sources are split in multiple directories, more or less divided by -module type (apps/ channels/ funcs/ res/ ...) or by function, for the main -binary (main/ pbx/). - - -TO BE COMPLETED - - ------------------------------------------------ -Welcome to the Asterisk development community! -Meet you on the asterisk-dev mailing list. -Subscribe at http://lists.digium.com! - --- The Asterisk.org Development Team diff --git a/doc/HOWTO_collect_debug_information.txt b/doc/HOWTO_collect_debug_information.txt deleted file mode 100644 index b9a04ae6b..000000000 --- a/doc/HOWTO_collect_debug_information.txt +++ /dev/null @@ -1,89 +0,0 @@ -=============================================================================== -=== -=== HowTo: Collect Debug Information for the Asterisk Issue Tracker -=== -=== Written by: Paul Belanger -=== Last updated: 2010-04-12 -=============================================================================== - -This document will provide instructions on how to collect debugging logs from an -Asterisk machine, for the purpose of helping bug marshals troubleshoot an issue -on https://issues.asterisk.org -------------------------------------------------------------------------------- ---- PREREQUISITES -------------------------------------------------------------------------------- - -- Asterisk 1.4.30 or greater. - -------------------------------------------------------------------------------- ---- STEPS -------------------------------------------------------------------------------- - -1. Edit the logger.conf file to enable debug output to your filesystem. - - Add the following line. The word "myDebugLog" can be changed to anything you - want, as that is the filename the logging will be written to. A good example - might be something like: issue_12345_full_log - - myDebugLog => notice,warning,error,debug,verbose,dtmf - -2. From the Asterisk CLI, restart the logger module: - - *CLI> core set verbose 15 - *CLI> core set debug 15 - *CLI> module reload logger - - Optionally, if you've used this file to record data previously, then rotate - the logs: - - *CLI> logger rotate - -2.1. Depending on your issue, be sure to enable the channel driver logging. - - SIP (1.6.0 or higher) - - *CLI> sip set debug on - - SIP (1.4) - - *CLI> sip set debug - - IAX2 (1.6.0 or higher) - - *CLI> iax2 set debug on - - IAX2 (1.4) - - *CLI> iax2 set debug - -3. Reproduce your issue. - -4. Once finished, be sure to disable the extra debbuging: - - *CLI> core set verbose 0 - *CLI> core set debug 0 - -4.1. Again, remember to disable any extra logging if you enabled it in the - channel driver. - - SIP (1.4 or higher) - - *CLI> sip set debug off - - IAX2 (1.4 or higher) - - *CLI> iax2 set debug off - -5. Upload the file located in /var/log/asterisk/myDebugLog to the issue tracker. - - *** IMPORTANT *** - Do NOT post the output of your file as a comment. This clutters the issue - and will only result in your comment being deleted. - -6. Disable logging to the filesystem. Edit the logger.conf file and comment out - or delete the line you added in step 1. Using a semi-colon as the first - character on the line will comment out the line. - - Then reload the logger module like in step 2: - - *CLI> module reload logger diff --git a/doc/India-CID.txt b/doc/India-CID.txt deleted file mode 100644 index 5961bb555..000000000 --- a/doc/India-CID.txt +++ /dev/null @@ -1,75 +0,0 @@ -India finds itself in a unique situation (hopefully). It has several -telephone line providers, and they are not all using the same CID -signalling; and the CID signalling is not like other countries. - -In order to help those in India quickly find to the CID signalling -system that their carrier uses (or range of them), and get the -configs right with a minimal amount of experimentation, this file -is provided. Not all carriers are covered, and not all mentioned -below are complete. Those with updates to this table should post -the new information on bug 6683 of the asterisk bug tracker. - - ---------------------------------------------------------- -Provider: Bharti (is this BSNL?) -Config: cidstart=polarity_in - cidsignalling=dtmf -Results: ? (this should work), but needs to be tested? -tested by: --------------------------------------------------------- - -Provider: VSNL -Config: - -Results: ? -tested by: --------------------------------------------------------- - -Provider: BSNL -Config: cid_start=ring - cid_signalling=dtmf - -Results: ? -tested by: (abhi) --------------------------------------------------------- - -Provider: MTNL, old BSNL -Config: cidsignalling = v23 - cidstart=ring - -Results: works -tested by: (enterux) --------------------------------------------------------- - -Provider: MTNL (Delhi) -Config: cidsignalling = v23 - cidstart = ring - -cidsignalling = dtmf -cidstart = polarity_IN - -cidsignalling = dtmf -cidstart = polarity - -Results: fails -tested by: brealer --------------------------------------------------------- - -Provider: TATA -Config: cidsignalling = dtmf - cidstart=polarity_IN - -Results: works -tested by: brealer ---------------------------------------------------------- - -Asterisk still doesn't work with some of the CID scenarios in India. -If you are in India, and not able to make CID work with any of the -permutations of cidsignalling and cidstart, it could be that this -particular situation is not covered by Asterisk. A good course of -action would be to get in touch with the provider, and find out from -them exactly how their CID signalling works. Describe this to us, -and perhaps someone will be able to extend the code to cover their -signalling. - - diff --git a/doc/PEERING b/doc/PEERING deleted file mode 100644 index 1a1a25c74..000000000 --- a/doc/PEERING +++ /dev/null @@ -1,503 +0,0 @@ -\begin{verbatim} - - DIGIUM GENERAL PEERING AGREEMENT (TM) - Version 1.0.0, September 2004 - Copyright (C) 2004 Digium, Inc. - 445 Jan Davis Drive, Huntsville, AL 35806 USA - - Everyone is permitted to copy and distribute complete verbatim copies - of this General Peering Agreement provided it is not modified in any - manner. - - ------------------------------------------------------ - - DIGIUM GENERAL PEERING AGREEMENT - - PREAMBLE - - For most of the history of telecommunications, the power of being able -to locate and communicate with another person in a system, be it across -a hall or around the world, has always centered around a centralized -authority -- from a local PBX administrator to regional and national -RBOCs, generally requiring fees, taxes or regulation. By contrast, -DUNDi is a technology developed to provide users the freedom to -communicate with each other without the necessity of any centralized -authority. This General Peering Agreement ("GPA") is used by individual -parties (each, a "Participant") to allow them to build the E164 trust -group for the DUNDi protocol. - - To protect the usefulness of the E164 trust group for those who use -it, while keeping the system wholly decentralized, it is necessary to -replace many of the responsibilities generally afforded to a company or -government agency, with a set of responsibilities implemented by the -parties who use the system, themselves. It is the goal of this document -to provide all the protections necessary to keep the DUNDi E164 trust -group useful and reliable. - - The Participants wish to protect competition, promote innovation and -value added services and make this service valuable both commercially -and non-commercially. To that end, this GPA provides special terms and -conditions outlining some permissible and non-permissible revenue -sources. - - This GPA is independent of any software license or other license -agreement for a program or technology employing the DUNDi protocol. For -example, the implementation of DUNDi used by Asterisk is covered under a -separate license. Each Participant is responsible for compliance with -any licenses or other agreements governing use of such program or -technology that they use to peer. - - You do not have to execute this GPA to use a program or technology -employing the DUNDi protocol, however if you do not execute this GPA, -you will not be able to peer using DUNDi and the E164 context with -anyone who is a member of the trust group by virtue of their having -executed this GPA with another member. - -The parties to this GPA agree as follows: - - 0. DEFINITIONS. As used herein, certain terms shall be defined as -follows: - - (a) The term "DUNDi" means the DUNDi protocol as published by - Digium, Inc. or its successor in interest with respect to the - DUNDi protocol specification. - - (b) The terms "E.164" and "E164" mean ITU-T specification E.164 as - published by the International Telecommunications Union (ITU) in - May, 1997. - - (c) The term "Service" refers to any communication facility (e.g., - telephone, fax, modem, etc.), identified by an E.164-compatible - number, and assigned by the appropriate authority in that - jurisdiction. - - (d) The term "Egress Gateway" refers an Internet facility that - provides a communications path to a Service or Services that may - not be directly addressable via the Internet. - - (e) The term "Route" refers to an Internet address, policies, and - other characteristics defined by the DUNDi protocol and - associated with the Service, or the Egress Gateway which - provides access to the specified Service. - - (f) The term "Propagate" means to accept or transmit Service and/or - Egress Gateway Routes only using the DUNDi protocol and the - DUNDi context "e164" without regard to case, and does not apply - to the exchange of information using any other protocol or - context. - - (g) The term "Peering System" means the network of systems that - Propagate Routes. - - (h) The term "Subscriber" means the owner of, or someone who - contracts to receive, the services identified by an E.164 - number. - - (i) The term "Authorizing Individual" means the Subscriber to a - number who has authorized a Participant to provide Routes - regarding their services via this Peering System. - - (j) The term "Route Authority" refers to a Participant that provides - an original source of said Route within the Peering System. - Routes are propagated from the Route Authorities through the - Peering System and may be cached at intermediate points. There - may be multiple Route Authorities for any Service. - - (k) The term "Participant" (introduced above) refers to any member - of the Peering System. - - (l) The term "Service Provider" refers to the carrier (e.g., - exchange carrier, Internet Telephony Service Provider, or other - reseller) that provides communication facilities for a - particular Service to a Subscriber, Customer or other End User. - - (m) The term "Weight" refers to a numeric quality assigned to a - Route as per the DUNDi protocol specification. The current - Weight definitions are shown in Exhibit A. - - 1. PEERING. The undersigned Participants agree to Propagate Routes -with each other and any other member of the Peering System and further -agree not to Propagate DUNDi Routes with a third party unless they have -first have executed this GPA (in its unmodified form) with such third -party. The Participants further agree only to Propagate Routes with -Participants whom they reasonably believe to be honoring the terms of -the GPA. Participants may not insert, remove, amend, or otherwise -modify any of the terms of the GPA. - - 2. ACCEPTABLE USE POLICY. The DUNDi protocol contains information -that reflect a Subscriber's or Egress Gateway's decisions to receive -calls. In addition to the terms and conditions set forth in this GPA, -the Participants agree to honor the intent of restrictions encoded in -the DUNDi protocol. To that end, Participants agree to the following: - - (a) A Participant may not utilize or permit the utilization of - Routes for which the Subscriber or Egress Gateway provider has - indicated that they do not wish to receive "Unsolicited Calls" - for the purpose of making an unsolicited phone call on behalf of - any party or organization. - - (b) A Participant may not utilize or permit the utilization of - Routes which have indicated that they do not wish to receive - "Unsolicited Commercial Calls" for the purpose of making an - unsolicited phone call on behalf of a commercial organization. - - (c) A Participant may never utilize or permit the utilization of any - DUNDi route for the purpose of making harassing phone calls. - - (d) A Party may not utilize or permit the utilization of DUNDi - provided Routes for any systematic or random calling of numbers - (e.g., for the purpose of locating facsimile, modem services, or - systematic telemarketing). - - (e) Initial control signaling for all communication sessions that - utilize Routes obtained from the Peering System must be sent - from a member of the Peering System to the Service or Egress - Gateway identified in the selected Route. For example, 'SIP - INVITES' and IAX2 "NEW" commands must be sent from the - requesting DUNDi node to the terminating Service. - - (f) A Participant may not disclose any specific Route, Service or - Participant contact information obtained from the Peering System - to any party outside of the Peering System except as a - by-product of facilitating communication in accordance with - section 2e (e.g., phone books or other databases may not be - published, but the Internet addresses of the Egress Gateway or - Service does not need to be obfuscated.) - - (g) The DUNDi Protocol requires that each Participant include valid - contact information about itself (including information about - nodes connected to each Participant). Participants may use or - disclose the contact information only to ensure enforcement of - legal furtherance of this Agreement. - - 3. ROUTES. The Participants shall only propagate valid Routes, as -defined herein, through the Peering System, regardless of the original -source. The Participants may only provide Routes as set forth below, -and then only if such Participant has no good faith reason to believe -such Route to be invalid or unauthorized. - - (a) A Participant may provide Routes if each Route has as its - original source another member of the Peering System who has - duly executed the GPA and such Routes are provided in accordance - with this Agreement; provided that the Routes are not modified - (e.g., with regards to existence, destination, technology or - Weight); or - - (b) A Participant may provide Routes for Services with any Weight - for which it is the Subscriber; or - - (c) A Participant may provide Routes for those Services whose - Subscriber has authorized the Participant to do so, provided - that the Participant is able to confirm that the Authorizing - Individual is the Subscriber through: - - i. a written statement of ownership from the Authorizing - Individual, which the Participant believes in good faith - to be accurate (e.g., a phone bill with the name of the - Authorizing Individual and the number in question); or - - ii. the Participant's own direct personal knowledge that the - Authorizing Individual is the Subscriber. - - (d) A Participant may provide Routes for Services, with Weight in - accordance with the Current DUNDi Specification, if it can in - good faith provide an Egress Gateway to that Service on the - traditional telephone network without cost to the calling party. - - 4. REVOCATION. A Participant must provide a free, easily accessible -mechanism by which a Subscriber may revoke permission to act as a Route -Authority for his Service. A Participant must stop acting as a Route -Authority for that Service within 7 days after: - - (a) receipt of a revocation request; - - (b) receiving other notice that the Service is no longer valid; or - - (c) determination that the Subscriber's information is no longer - accurate (including that the Subscriber is no longer the service - owner or the service owner's authorized delegate). - - 5. SERVICE FEES. A Participant may charge a fee to act as a Route -Authority for a Service, with any Weight, provided that no Participant -may charge a fee to propagate the Route received through the Peering -System. - - 6. TOLL SERVICES. No Participant may provide Routes for any Services -that require payment from the calling party or their customer for -communication with the Service. Nothing in this section shall prohibit -a Participant from providing routes for Services where the calling party -may later enter into a financial transaction with the called party -(e.g., a Participant may provide Routes for calling cards services). - - 7. QUALITY. A Participant may not intentionally impair communication -using a Route provided to the Peering System (e.g. by adding delay, -advertisements, reduced quality). If for any reason a Participant is -unable to deliver a call via a Route provided to the Peering System, -that Participant shall return out-of-band Network Congestion -notification (e.g. "503 Service Unavailable" with SIP protocol or -"CONGESTION" with IAX protocol). - - 8. PROTOCOL COMPLIANCE. Participants agree to Propagate Routes in -strict compliance with current DUNDi protocol specifications. - - 9. ADMINISTRATIVE FEES. A Participant may charge (but is not required -to charge) another Participant a reasonable fee to cover administrative -expenses incurred in the execution of this Agreement. A Participant may -not charge any fee to continue the relationship or to provide Routes to -another Participant in the Peering System. - - 10. CALLER IDENTIFICATION. A Participant will make a good faith effort -to ensure the accuracy and appropriate nature of any caller -identification that it transmits via any Route obtained from the Peering -System. Caller identification shall at least be provided as a valid -E.164 number. - - 11. COMPLIANCE WITH LAWS. The Participants are solely responsible for -determining to what extent, if any, the obligations set forth in this -GPA conflict with any laws or regulations their region. A Participant -may not provide any service or otherwise use DUNDi under this GPA if -doing so is prohibited by law or regulation, or if any law or regulation -imposes requirements on the Participant that are inconsistent with the -terms of this GPA or the Acceptable Use Policy. - - 12. WARRANTY. EACH PARTICIPANT WARRANTS TO THE OTHER PARTICIPANTS THAT -IT MADE, AND WILL CONTINUE TO MAKE, A GOOD FAITH EFFORT TO AUTHENTICATE -OTHERS IN THE PEERING SYSTEM AND TO PROVIDE ACCURATE INFORMATION IN -ACCORDANCE WITH THE TERMS OF THIS GPA. THIS WARRANTY IS MADE BETWEEN -THE PARTICIPANTS, AND THE PARTICIPANTS MAY NOT EXTEND THIS WARRANTY TO -ANY NON-PARTICIPANT INCLUDING END-USERS. - - 13. DISCLAIMER OF WARRANTIES. THE PARTICIPANTS UNDERSTAND AND AGREE -THAT ANY SERVICE PROVIDED AS A RESULT OF THIS GPA IS "AS IS." EXCEPT FOR -THOSE WARRANTIES OTHERWISE EXPRESSLY SET FORTH HEREIN, THE PARTICIPANTS -DISCLAIM ANY REPRESENTATIONS OR WARRANTIES OF ANY KIND OR NATURE, -EXPRESS OR IMPLIED, AS TO THE CONDITION, VALUE OR QUALITIES OF THE -SERVICES PROVIDED HEREUNDER, AND SPECIFICALLY DISCLAIM ANY -REPRESENTATION OR WARRANTY OF MERCHANTABILITY, SUITABILITY OR FITNESS -FOR A PARTICULAR PURPOSE OR AS TO THE CONDITION OR WORKMANSHIP THEREOF, -OR THE ABSENCE OF ANY DEFECTS THEREIN, WHETHER LATENT OR PATENT, -INCLUDING ANY WARRANTIES ARISING FROM A COURSE OF DEALING, USAGE OR -TRADE PRACTICE. EXCEPT AS EXPRESSLY PROVIDED HEREIN, THE PARTICIPANTS -EXPRESSLY DISCLAIM ANY REPRESENTATIONS OR WARRANTIES THAT THE PEERING -SERVICE WILL BE CONTINUOUS, UNINTERRUPTED OR ERROR-FREE, THAT ANY DATA -SHARED OR OTHERWISE MADE AVAILABLE WILL BE ACCURATE OR COMPLETE OR -OTHERWISE COMPLETELY SECURE FROM UNAUTHORIZED ACCESS. - - 14. LIMITATION OF LIABILITIES. NO PARTICIPANT SHALL BE LIABLE TO ANY -OTHER PARTICIPANT FOR INCIDENTAL, INDIRECT, CONSEQUENTIAL, SPECIAL, -PUNITIVE OR EXEMPLARY DAMAGES OF ANY KIND (INCLUDING LOST REVENUES OR -PROFITS, LOSS OF BUSINESS OR LOSS OF DATA) IN ANY WAY RELATED TO THIS -GPA, WHETHER IN CONTRACT OR IN TORT, REGARDLESS OF WHETHER SUCH -PARTICIPANT WAS ADVISED OF THE POSSIBILITY THEREOF. - - 15. END-USER AGREEMENTS. The Participants may independently enter -into agreements with end-users to provide certain services (e.g., fees -to a Subscriber to originate Routes for that Service). To the extent -that provision of these services employs the Peering System, the Parties -will include in their agreements with their end-users terms and -conditions consistent with the terms of this GPA with respect to the -exclusion of warranties, limitation of liability and Acceptable Use -Policy. In no event may a Participant extend the warranty described in -Section 12 in this GPA to any end-users. - - 16. INDEMNIFICATION. Each Participant agrees to defend, indemnify and -hold harmless the other Participant or third-party beneficiaries to this -GPA (including their affiliates, successors, assigns, agents and -representatives and their respective officers, directors and employees) -from and against any and all actions, suits, proceedings, -investigations, demands, claims, judgments, liabilities, obligations, -liens, losses, damages, expenses (including, without limitation, -attorneys' fees) and any other fees arising out of or relating to (i) -personal injury or property damage caused by that Participant, its -employees, agents, servants, or other representatives; (ii) any act or -omission by the Participant, its employees, agents, servants or other -representatives, including, but not limited to, unauthorized -representations or warranties made by the Participant; or (iii) any -breach by the Participant of any of the terms or conditions of this GPA. - - 17. THIRD PARTY BENEFICIARIES. This GPA is intended to benefit those -Participants who have executed the GPA and who are in the Peering -System. It is the intent of the Parties to this GPA to give to those -Participants who are in the Peering System standing to bring any -necessary legal action to enforce the terms of this GPA. - - 18. TERMINATION. Any Participant may terminate this GPA at any time, -with or without cause. A Participant that terminates must immediately -cease to Propagate. - - 19. CHOICE OF LAW. This GPA and the rights and duties of the Parties -hereto shall be construed and determined in accordance with the internal -laws of the State of New York, United States of America, without regard -to its conflict of laws principles and without application of the United -Nations Convention on Contracts for the International Sale of Goods. - - 20. DISPUTE RESOLUTION. Unless otherwise agreed in writing, the -exclusive procedure for handling disputes shall be as set forth herein. -Notwithstanding such procedures, any Participant may, at any time, seek -injunctive relief in addition to the process described below. - - (a) Prior to mediation or arbitration the disputing Participants - shall seek informal resolution of disputes. The process shall be - initiated with written notice of one Participant to the other - describing the dispute with reasonable particularity followed - with a written response within ten (10) days of receipt of - notice. Each Participant shall promptly designate an executive - with requisite authority to resolve the dispute. The informal - procedure shall commence within ten (10) days of the date of - response. All reasonable requests for non-privileged information - reasonably related to the dispute shall be honored. If the - dispute is not resolved within thirty (30) days of commencement - of the procedure either Participant may proceed to mediation or - arbitration pursuant to the rules set forth in (b) or (c) below. - - (b) If the dispute has not been resolved pursuant to (a) above or, - if the disputing Participants fail to commence informal dispute - resolution pursuant to (a) above, either Participant may, in - writing and within twenty (20) days of the response date noted - in (a) above, ask the other Participant to participate in a one - (1) day mediation with an impartial mediator, and the other - Participant shall do so. Each Participant will bear its own - expenses and an equal share of the fees of the mediator. If the - mediation is not successful the Participants may proceed with - arbitration pursuant to (c) below. - - (c) If the dispute has not been resolved pursuant to (a) or (b) - above, the dispute shall be promptly referred, no later than one - (1) year from the date of original notice and subject to - applicable statute of limitations, to binding arbitration in - accordance with the UNCITRAL Arbitration Rules in effect on the - date of this contract. The appointing authority shall be the - International Centre for Dispute Resolution. The case shall be - administered by the International Centre for Dispute Resolution - under its Procedures for Cases under the UNCITRAL Arbitration - Rules. Each Participant shall bear its own expenses and shall - share equally in fees of the arbitrator. All arbitrators shall - have substantial experience in information technology and/or in - the telecommunications business and shall be selected by the - disputing participants in accordance with UNCITRAL Arbitration - Rules. If any arbitrator, once selected is unable or unwilling - to continue for any reason, replacement shall be filled via the - process described above and a re-hearing shall be conducted. The - disputing Participants will provide each other with all - requested documents and records reasonably related to the - dispute in a manner that will minimize the expense and - inconvenience of both parties. Discovery will not include - depositions or interrogatories except as the arbitrators - expressly allow upon a showing of need. If disputes arise - concerning discovery requests, the arbitrators shall have sole - and complete discretion to resolve the disputes. The parties and - arbitrator shall be guided in resolving discovery disputes by - the Federal Rules of Civil Procedure. The Participants agree - that time of the essence principles shall guide the hearing and - that the arbitrator shall have the right and authority to issue - monetary sanctions in the event of unreasonable delay. The - arbitrator shall deliver a written opinion setting forth - findings of fact and the rationale for the award within thirty - (30) days following conclusion of the hearing. The award of the - arbitrator, which may include legal and equitable relief, but - which may not include punitive damages, will be final and - binding upon the disputing Participants, and judgment may be - entered upon it in accordance with applicable law in any court - having jurisdiction thereof. In addition to award the - arbitrator shall have the discretion to award the prevailing - Participant all or part of its attorneys' fees and costs, - including fees associated with arbitrator, if the arbitrator - determines that the positions taken by the other Participant on - material issues of the dispute were without substantial - foundation. Any conflict between the UNCITRAL Arbitration Rules - and the provisions of this GPA shall be controlled by this GPA. - - 21. INTEGRATED AGREEMENT. This GPA, constitutes the complete -integrated agreement between the parties concerning the subject matter -hereof. All prior and contemporaneous agreements, understandings, -negotiations or representations, whether oral or in writing, relating to -the subject matter of this GPA are superseded and canceled in their -entirety. - - 22. WAIVER. No waiver of any of the provisions of this GPA shall be -deemed or shall constitute a waiver of any other provision of this GPA, -whether or not similar, nor shall such waiver constitute a continuing -waiver unless otherwise expressly so provided in writing. The failure -of either party to enforce at any time any of the provisions of this -GPA, or the failure to require at any time performance by either party -of any of the provisions of this GPA, shall in no way be construed to be -a present or future waiver of such provisions, nor in any way affect the -ability of a Participant to enforce each and every such provision -thereafter. - - 23. INDEPENDENT CONTRACTORS. Nothing in this GPA shall make the -Parties partners, joint venturers, or otherwise associated in or with -the business of the other. Parties are, and shall always remain, -independent contractors. No Participant shall be liable for any debts, -accounts, obligations, or other liabilities of the other Participant, -its agents or employees. No party is authorized to incur debts or other -obligations of any kind on the part of or as agent for the other. This -GPA is not a franchise agreement and does not create a franchise -relationship between the parties, and if any provision of this GPA is -deemed to create a franchise between the parties, then this GPA shall -automatically terminate. - - 24. CAPTIONS AND HEADINGS. The captions and headings used in this GPA -are used for convenience only and are not to be given any legal effect. - - 25. EXECUTION. This GPA may be executed in counterparts, each of which -so executed will be deemed to be an original and such counterparts -together will constitute one and the same Agreement. The Parties shall -transmit to each other a signed copy of the GPA by any means that -faithfully reproduces the GPA along with the Signature. For purposes of -this GPA, the term "signature" shall include digital signatures as -defined by the jurisdiction of the Participant signing the GPA. - - Exhibit A - -Weight Range Requirements - -0-99 May only be used under authorization of Owner - -100-199 May only be used by the Owner's service - provider, regardless of authorization. - -200-299 Reserved -- do not use for e164 context. - -300-399 May only be used by the owner of the code under - which the Owner's number is a part of. - -400-499 May be used by any entity providing access via - direct connectivity to the Public Switched - Telephone Network. - -500-599 May be used by any entity providing access via - indirect connectivity to the Public Switched - Telephone Network (e.g. Via another VoIP - provider) - -600- Reserved-- do not use for e164 context. - - Participant Participant - -Company: - -Address: - -Email: - - - _________________________ _________________________ - Authorized Signature Authorized Signature - -Name: - - -END OF GENERAL PEERING AGREEMENT - ------------------------------------------------- - -How to Peer using this GPA If you wish to exchange routing information -with parties using the e164 DUNDi context, all you must do is execute -this GPA with any member of the Peering System and you will become a -member of the Peering System and be able to make Routes available in -accordance with this GPA. - -DUNDi, IAX, Asterisk and GPA are trademarks of Digium, Inc. - -\end{verbatim} diff --git a/doc/README.txt b/doc/README.txt new file mode 100644 index 000000000..68a87e11e --- /dev/null +++ b/doc/README.txt @@ -0,0 +1,10 @@ +The vast majority of the Asterisk project documentation has been moved to the +project wiki: + + http://wiki.asterisk.org/ + +Asterisk release tarballs contain an export of the wiki in PDF and plain text +form, which you can find in: + + doc/AST.pdf + doc/AST.txt diff --git a/doc/advice_of_charge.txt b/doc/advice_of_charge.txt deleted file mode 100644 index 9673178ad..000000000 --- a/doc/advice_of_charge.txt +++ /dev/null @@ -1,189 +0,0 @@ -================ -Advice of Charge -================ - -Written by: David Vossel -Initial version: 04-19-2010 -Email: dvossel@digium.com - -This document is designed to give an overview of how to configure and -generate Advice of Charge along with a detailed explanation of how each -option works. - --------------------------------------- -| READ THIS FIRST | --------------------------------------- -PLEASE REPORT ANY ISSUES ENCOUNTERED WHILE USING AOC. This feature -has had very little community feedback so far. If you are using this -feature please share with us any problems you are having and any -improvements that could make this feature more useful. Thank you! - --------------------------------------- -| Terminology | --------------------------------------- -AOC: Advice of Charge - -AOC-S: Advice of Charge message sent at the beginning of a call during -call setup. This message contains a list of rates associated with the -call. - -AOC-D: Advice of Charge message sent during the call. This message -is typically used to update the endpoint with the current call charge. - -AOC-E: Advice of Charge message sent at the end of a call. This -message is used to indicate to the endpoint the final call charge. - -AMI: Asterisk Manager Interface. This interface is used to generate -AOC messages and listen for AOC events. - --------------------------------------- -| AOC in chan_dahdi | --------------------------------------- ------ LibPRI Support: -ETSI, or euroisdn, is the only switchtype that LibPRI currently supports -for AOC. - ------ Enable AOC Pass-through in chan_dahdi -To enable AOC pass-through between the ISDN and Asterisk use the -'aoc_enable' config option. This option allows for any combination -of AOC-S, AOC-D, and AOC-E to be enabled or disabled. - -For example: -aoc_enable=s,d,e ; enables pass-through of AOC-S, AOC-D, and AOC-E - -aoc_enable=s,d ; enables pass-through of AOC-S and AOC-D. Rejects - ; AOC-E and AOC-E request messages - -Since AOC messages are often transported on facility messages, the -'facilityenable' option must be enabled as well to fully support AOC -pass-through. - ------ Handling AOC-E in chan_dahdi -Whenever a dahdi channel receives an AOC-E message from Asterisk, it -stores that message to deliver it at the appropriate time during call -termination. This means that if two AOC-E messages are received on the -same call, the last one will override the first one and only one AOC-E -message will be sent during call termination. - -There are some tricky situations involving the final AOC-E message. During -a bridged call, if the endpoint receiving the AOC messages terminates -the call before the endpoint delivering the AOC does, the final AOC-E -message sent by the sending side during termination will never make it to -the receiving end because Asterisk will have already torn down that channel. -This is where the chan_dahdi.conf 'aoce_delayhangup' option comes into play. - -By enabling 'aoce_delayhangup', anytime a hangup is initiated by the -ISDN side of an Asterisk channel, instead of hanging up the channel, -the channel sends a unique internal AOC-E termination request to its bridge -channel. This indicates it is about to hangup and wishes to receive the -final AOC-E message from the bridged channel before completely tearing -down. If the bridged channel knows what to do with this AOC-E termination -request, it will do whatever is necessary to indicate to its endpoint that -the call is being terminated without actually hanging up the Asterisk channel. -This allows the final AOC-E message to come in and be sent across the bridge -while both channels are still up. If the channel delaying its hangup for -the final AOC-E message times out, the call will be torn down just as it -normally would. In chan_dahdi the timeout period is 1/2 the T305 timer -which by default is 15 seconds. - -'aoce_delayhangup' currently only works when both bridged channels are -dahdi_channels. If a SIP channel receives an AOC-E termination request, it -just responds by immediately hanging up the channel. Using this option when -bridged to any channel technology besides SIP or DAHDI will result in the -15 second timeout period before tearing down the call completely. - ------ Requesting AOC services -AOC can be requested on a call by call basis using the DAHDI dialstring -option, A(). The A() option takes in 's', 'd', and 'e' parameters which -represent the three types of AOC messages, AOC-S, AOC-D, and AOC-E. By using -this option Asterisk will indicate to the endpoint during call setup that it -wishes to receive the specified forms of AOC during the call. - -Example Usage in extensions.conf -exten => 1111,1,Dial(DAHDI/g1/1112/A(s,d,e) ; requests AOC-S, AOC-D, and AOC-E on - ; call setup -exten => 1111,1,Dial(DAHDI/g1/1112/A(d,e) ; requests only AOC-D, and AOC-E on - ; call setup - --------------------------------------- -| AOC in chan_sip | --------------------------------------- -Asterisk supports a very basic way of sending AOC on a SIP channel to Snom -phones using an AOC specification designed by Snom. This support is limited -to the sending of AOC-D and AOC-E pass-through messages. No support for -AOC-E on call termination is present, so if the Snom endpoint receiving the -AOC messages from Asterisk terminates the call, the channel will be torn -down before the phone can receive the final AOC-E message. - -To enable passthrough of AOC messages via the snom specification, use -the 'snom_aoc_enabled' option in sip.conf. - --------------------------------------- -| Generate AOC Messages via AMI | --------------------------------------- -Asterisk supports a way to generate AOC messages on a channel via -the AMI action AOCMessage. At the moment the AOCMessage action is limited -to AOC-D and AOC-E message generation. There are some limitations -involved with delivering the final AOC-E message as well. The AOCMessage -action has its own detailed parameter documentation so this discussion will -focus on higher level use. When generating AOC messages on a Dahdi channel -first make sure the appropriate chan_dahdi.conf options are enabled. Without -enabling 'aoc_enable' correctly for pass-through the AOC messages will never -make it out the pri. The same goes with SIP, the 'snom_aoc_enabled' option -must be configured before messages can successfully be set to the endpoint. - ------ AOC-D Message Generation -AOC-D message generation can happen anytime throughout the call. This -message type is very straight forward. - -Example: AOCMessage action generating AOC-D currency message with Success -response. - -Action: AOCMessage -Channel: DAHDI/i1/1111-1 -MsgType: d -ChargeType: Currency -CurrencyAmount: 16 -CurrencyName: USD -CurrencyMultiplier: OneThousandth -AOCBillingId: Normal -ActionID: 1234 - -Response: Success -ActionID: 1234 -Message: AOC Message successfully queued on channel - ------ AOC-E Message Generation -AOC-E messages are sent during call termination and represent the final charge -total for the call. Since Asterisk call termination results in the channel -being destroyed, it is currently not possible for the AOCMessage AMI action to -be used to send the final AOC-E message on call hangup. There is however a -work around for this issue that can be used for Dahdi channels. By default -chan_dahdi saves any AOC-E message it receives from Asterisk during a call and -waits to deliver that message during call termination. If multiple AOC-E messages -are received from Asterisk on the same Dahdi channel, only the last message received -is stored for delivery. This means that each new AOC-E message received on the -channel overrides the previous one. Knowing this the final AOC-E message can be -continually updated on a Dahdi channel until call termination occurs allowing -the last update to be sent on hangup. This method is only as accurate as the -intervals in which it is updated, but allows some form of AOC-E to be generated. - -Example: AOCMessage action generating AOC-E unit message with Success response. - -Action: AOCMessage -Channel: DAHDI/i1/1111-1 -MsgType: e -ChargeType: Unit -UnitAmount(0): 111 -UnitType(0): 6 -UnitAmount(1): 222 -UnitType(1): 5 -UnitAmount(2): 333 -UnitType(3): 4 -UnitAmount(4): 444 -AOCBillingId: Normal -ActionID: 1234 - -Response: Success -ActionID: 1234 -Message: AOC Message successfully queued on channel diff --git a/doc/asterisk-mib.txt b/doc/asterisk-mib.txt deleted file mode 100644 index e7d6c1719..000000000 --- a/doc/asterisk-mib.txt +++ /dev/null @@ -1,778 +0,0 @@ -ASTERISK-MIB DEFINITIONS ::= BEGIN - -IMPORTS - OBJECT-TYPE, MODULE-IDENTITY, Integer32, Counter32, TimeTicks, - Unsigned32, Gauge32 - FROM SNMPv2-SMI - - TEXTUAL-CONVENTION, DisplayString, TruthValue - FROM SNMPv2-TC - - digium - FROM DIGIUM-MIB; - -asterisk MODULE-IDENTITY - LAST-UPDATED "200806202025Z" - ORGANIZATION "Digium, Inc." - CONTACT-INFO - "Mark A. Spencer - Postal: Digium, Inc. - 445 Jan Davis Drive - Huntsville, AL 35806 - USA - Tel: +1 256 428 6000 - Email: markster@digium.com - - Thorsten Lockert - Postal: Voop AS - Boehmergaten 42 - NO-5057 Bergen - Norway - Tel: +47 5598 7200 - Email: tholo@voop.no" - DESCRIPTION - "Asterisk is an Open Source PBX. This MIB defined - objects for managing Asterisk instances." - REVISION "200806202025Z" - DESCRIPTION - "smilint police -- - Add missing imports; fix initial capitalization - of enumeration elements; add missing range - restrictions for Integer32 indices, correct - spelling of astChanCidANI in its definition. - Addresses bug 12905. - jeffg@opennms.org" - REVISION "200708211450Z" - DESCRIPTION - "Add total and current call counter statistics." - REVISION "200603061840Z" - DESCRIPTION - "Change audio codec identification from 3kAudio to - Audio3k to conform better with specification. - - Expand on contact information." - REVISION "200602041900Z" - DESCRIPTION - "Initial published revision." - ::= { digium 1 } - -asteriskVersion OBJECT IDENTIFIER ::= { asterisk 1 } -asteriskConfiguration OBJECT IDENTIFIER ::= { asterisk 2 } -asteriskModules OBJECT IDENTIFIER ::= { asterisk 3 } -asteriskIndications OBJECT IDENTIFIER ::= { asterisk 4 } -asteriskChannels OBJECT IDENTIFIER ::= { asterisk 5 } - --- asteriskVersion - -astVersionString OBJECT-TYPE - SYNTAX DisplayString - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Text version string of the version of Asterisk that - the SNMP Agent was compiled to run against." - ::= { asteriskVersion 1 } - -astVersionTag OBJECT-TYPE - SYNTAX Unsigned32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "SubVersion revision of the version of Asterisk that - the SNMP Agent was compiled to run against -- this is - typically 0 for release-versions of Asterisk." - ::= { asteriskVersion 2 } - --- asteriskConfiguration - -astConfigUpTime OBJECT-TYPE - SYNTAX TimeTicks - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Time ticks since Asterisk was started." - ::= { asteriskConfiguration 1 } - -astConfigReloadTime OBJECT-TYPE - SYNTAX TimeTicks - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Time ticks since Asterisk was last reloaded." - ::= { asteriskConfiguration 2 } - -astConfigPid OBJECT-TYPE - SYNTAX Integer32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The process id of the running Asterisk process." - ::= { asteriskConfiguration 3 } - -astConfigSocket OBJECT-TYPE - SYNTAX DisplayString - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The control socket for giving Asterisk commands." - ::= { asteriskConfiguration 4 } - -astConfigCallsActive OBJECT-TYPE - SYNTAX Gauge32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The number of calls currently active on the Asterisk PBX." - ::= { asteriskConfiguration 5 } - -astConfigCallsProcessed OBJECT-TYPE - SYNTAX Counter32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "The total number of calls processed through the Asterisk PBX since last - restart." - ::= { asteriskConfiguration 6 } - --- asteriskModules - -astNumModules OBJECT-TYPE - SYNTAX Integer32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Number of modules currently loaded into Asterisk." - ::= { asteriskModules 1 } - --- asteriskIndications - -astNumIndications OBJECT-TYPE - SYNTAX Integer32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Number of indications currently defined in Asterisk." - ::= { asteriskIndications 1 } - -astCurrentIndication OBJECT-TYPE - SYNTAX DisplayString - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Default indication zone to use." - ::= { asteriskIndications 2 } - -astIndicationsTable OBJECT-TYPE - SYNTAX SEQUENCE OF AstIndicationsEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "Table with all the indication zones currently know to - the running Asterisk instance." - ::= { asteriskIndications 3 } - -astIndicationsEntry OBJECT-TYPE - SYNTAX AstIndicationsEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "Information about a single indication zone." - INDEX { astIndIndex } - ::= { astIndicationsTable 1 } - -AstIndicationsEntry ::= SEQUENCE { - astIndIndex Integer32, - astIndCountry DisplayString, - astIndAlias DisplayString, - astIndDescription DisplayString -} - -astIndIndex OBJECT-TYPE - SYNTAX Integer32 (1 .. 2147483647) - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Numerical index into the table of indication zones." - ::= { astIndicationsEntry 1 } - -astIndCountry OBJECT-TYPE - SYNTAX DisplayString - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Country for which the indication zone is valid, - typically this is the ISO 2-letter code of the country." - ::= { astIndicationsEntry 2 } - -astIndAlias OBJECT-TYPE - SYNTAX DisplayString - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "" - ::= { astIndicationsEntry 3 } - -astIndDescription OBJECT-TYPE - SYNTAX DisplayString - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Description of the indication zone, usually the full - name of the country it is valid for." - ::= { astIndicationsEntry 4 } - --- asteriskChannels - -astNumChannels OBJECT-TYPE - SYNTAX Gauge32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Current number of active channels." - ::= { asteriskChannels 1 } - -astChanTable OBJECT-TYPE - SYNTAX SEQUENCE OF AstChanEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "Table with details of the currently active channels - in the Asterisk instance." - ::= { asteriskChannels 2 } - -astChanEntry OBJECT-TYPE - SYNTAX AstChanEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "Details of a single channel." - INDEX { astChanIndex } - ::= { astChanTable 1 } - -AstChanEntry ::= SEQUENCE { - astChanIndex Integer32, - astChanName DisplayString, - astChanLanguage DisplayString, - astChanType DisplayString, - astChanMusicClass DisplayString, - astChanBridge DisplayString, - astChanMasq DisplayString, - astChanMasqr DisplayString, - astChanWhenHangup TimeTicks, - astChanApp DisplayString, - astChanData DisplayString, - astChanContext DisplayString, - astChanMacroContext DisplayString, - astChanMacroExten DisplayString, - astChanMacroPri Integer32, - astChanExten DisplayString, - astChanPri Integer32, - astChanAccountCode DisplayString, - astChanForwardTo DisplayString, - astChanUniqueId DisplayString, - astChanCallGroup Unsigned32, - astChanPickupGroup Unsigned32, - astChanState INTEGER, - astChanMuted TruthValue, - astChanRings Integer32, - astChanCidDNID DisplayString, - astChanCidNum DisplayString, - astChanCidName DisplayString, - astChanCidANI DisplayString, - astChanCidRDNIS DisplayString, - astChanCidPresentation DisplayString, - astChanCidANI2 Integer32, - astChanCidTON Integer32, - astChanCidTNS Integer32, - astChanAMAFlags INTEGER, - astChanADSI INTEGER, - astChanToneZone DisplayString, - astChanHangupCause INTEGER, - astChanVariables DisplayString, - astChanFlags BITS, - astChanTransferCap INTEGER -} - -astChanIndex OBJECT-TYPE - SYNTAX Integer32 (1 .. 2147483647) - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Index into the channel table." - ::= { astChanEntry 1 } - -astChanName OBJECT-TYPE - SYNTAX DisplayString - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Name of the current channel." - ::= { astChanEntry 2 } - -astChanLanguage OBJECT-TYPE - SYNTAX DisplayString - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Which language the current channel is configured to - use -- used mainly for prompts." - ::= { astChanEntry 3 } - -astChanType OBJECT-TYPE - SYNTAX DisplayString - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Underlying technology for the current channel." - ::= { astChanEntry 4 } - -astChanMusicClass OBJECT-TYPE - SYNTAX DisplayString - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Music class to be used for Music on Hold for this - channel." - ::= { astChanEntry 5 } - -astChanBridge OBJECT-TYPE - SYNTAX DisplayString - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Which channel this channel is currently bridged (in a - conversation) with." - ::= { astChanEntry 6 } - -astChanMasq OBJECT-TYPE - SYNTAX DisplayString - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Channel masquerading for us." - ::= { astChanEntry 7 } - -astChanMasqr OBJECT-TYPE - SYNTAX DisplayString - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Channel we are masquerading for." - ::= { astChanEntry 8 } - -astChanWhenHangup OBJECT-TYPE - SYNTAX TimeTicks - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "How long until this channel will be hung up." - ::= { astChanEntry 9 } - -astChanApp OBJECT-TYPE - SYNTAX DisplayString - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Current application for the channel." - ::= { astChanEntry 10 } - -astChanData OBJECT-TYPE - SYNTAX DisplayString - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Arguments passed to the current application." - ::= { astChanEntry 11 } - -astChanContext OBJECT-TYPE - SYNTAX DisplayString - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Current extension context." - ::= { astChanEntry 12 } - -astChanMacroContext OBJECT-TYPE - SYNTAX DisplayString - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Current macro context." - ::= { astChanEntry 13 } - -astChanMacroExten OBJECT-TYPE - SYNTAX DisplayString - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Current macro extension." - ::= { astChanEntry 14 } - -astChanMacroPri OBJECT-TYPE - SYNTAX Integer32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Current macro priority." - ::= { astChanEntry 15 } - -astChanExten OBJECT-TYPE - SYNTAX DisplayString - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Current extension." - ::= { astChanEntry 16 } - -astChanPri OBJECT-TYPE - SYNTAX Integer32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Current priority." - ::= { astChanEntry 17 } - -astChanAccountCode OBJECT-TYPE - SYNTAX DisplayString - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Account Code for billing." - ::= { astChanEntry 18 } - -astChanForwardTo OBJECT-TYPE - SYNTAX DisplayString - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Where to forward to if asked to dial on this - interface." - ::= { astChanEntry 19 } - -astChanUniqueId OBJECT-TYPE - SYNTAX DisplayString - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Unique Channel Identifier." - ::= { astChanEntry 20 } - -astChanCallGroup OBJECT-TYPE - SYNTAX Unsigned32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Call Group." - ::= { astChanEntry 21 } - -astChanPickupGroup OBJECT-TYPE - SYNTAX Unsigned32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Pickup Group." - ::= { astChanEntry 22 } - -astChanState OBJECT-TYPE - SYNTAX INTEGER { - stateDown(0), - stateReserved(1), - stateOffHook(2), - stateDialing(3), - stateRing(4), - stateRinging(5), - stateUp(6), - stateBusy(7), - stateDialingOffHook(8), - statePreRing(9) - } - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Channel state." - ::= { astChanEntry 23 } - -astChanMuted OBJECT-TYPE - SYNTAX TruthValue - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Transmission of voice data has been muted." - ::= { astChanEntry 24 } - -astChanRings OBJECT-TYPE - SYNTAX Integer32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Number of rings so far." - ::= { astChanEntry 25 } - -astChanCidDNID OBJECT-TYPE - SYNTAX DisplayString - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Dialled Number ID." - ::= { astChanEntry 26 } - -astChanCidNum OBJECT-TYPE - SYNTAX DisplayString - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Caller Number." - ::= { astChanEntry 27 } - -astChanCidName OBJECT-TYPE - SYNTAX DisplayString - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Caller Name." - ::= { astChanEntry 28 } - -astChanCidANI OBJECT-TYPE - SYNTAX DisplayString - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "ANI" - ::= { astChanEntry 29 } - -astChanCidRDNIS OBJECT-TYPE - SYNTAX DisplayString - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Redirected Dialled Number Service." - ::= { astChanEntry 30 } - -astChanCidPresentation OBJECT-TYPE - SYNTAX DisplayString - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Number Presentation/Screening." - ::= { astChanEntry 31 } - -astChanCidANI2 OBJECT-TYPE - SYNTAX Integer32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "ANI 2 (info digit)." - ::= { astChanEntry 32 } - -astChanCidTON OBJECT-TYPE - SYNTAX Integer32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Type of Number." - ::= { astChanEntry 33 } - -astChanCidTNS OBJECT-TYPE - SYNTAX Integer32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Transit Network Select." - ::= { astChanEntry 34 } - -astChanAMAFlags OBJECT-TYPE - SYNTAX INTEGER { - default(0), - omit(1), - billing(2), - documentation(3) - } - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "AMA Flags." - ::= { astChanEntry 35 } - -astChanADSI OBJECT-TYPE - SYNTAX INTEGER { - unknown(0), - available(1), - unavailable(2), - offHookOnly(3) - } - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Whether or not ADSI is detected on CPE." - ::= { astChanEntry 36 } - -astChanToneZone OBJECT-TYPE - SYNTAX DisplayString - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Indication zone to use for channel." - ::= { astChanEntry 37 } - -astChanHangupCause OBJECT-TYPE - SYNTAX INTEGER { - notDefined(0), - unregistered(3), - normal(16), - busy(17), - noAnswer(19), - congestion(34), - failure(38), - noSuchDriver(66) - } - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Why is the channel hung up." - ::= { astChanEntry 38 } - -astChanVariables OBJECT-TYPE - SYNTAX DisplayString - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Channel Variables defined for this channel." - ::= { astChanEntry 39 } - -astChanFlags OBJECT-TYPE - SYNTAX BITS { - wantsJitter(0), - deferDTMF(1), - writeInterrupt(2), - blocking(3), - zombie(4), - exception(5), - musicOnHold(6), - spying(7), - nativeBridge(8), - autoIncrementingLoop(9) - } - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Flags set on this channel." - ::= { astChanEntry 40 } - -astChanTransferCap OBJECT-TYPE - SYNTAX INTEGER { - speech(0), - digital(8), - restrictedDigital(9), - audio3k(16), - digitalWithTones(17), - video(24) - } - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Transfer Capabilities for this channel." - ::= { astChanEntry 41 } - -astNumChanTypes OBJECT-TYPE - SYNTAX Integer32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Number of channel types (technologies) supported." - ::= { asteriskChannels 3 } - -astChanTypeTable OBJECT-TYPE - SYNTAX SEQUENCE OF AstChanTypeEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "Table with details of the supported channel types." - ::= { asteriskChannels 4 } - -astChanTypeEntry OBJECT-TYPE - SYNTAX AstChanTypeEntry - MAX-ACCESS not-accessible - STATUS current - DESCRIPTION - "Information about a technology we support, including - how many channels are currently using this technology." - INDEX { astChanTypeIndex } - ::= { astChanTypeTable 1 } - -AstChanTypeEntry ::= SEQUENCE { - astChanTypeIndex Integer32, - astChanTypeName DisplayString, - astChanTypeDesc DisplayString, - astChanTypeDeviceState Integer32, - astChanTypeIndications Integer32, - astChanTypeTransfer Integer32, - astChanTypeChannels Gauge32 -} - -astChanTypeIndex OBJECT-TYPE - SYNTAX Integer32 (1 .. 2147483647) - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Index into the table of channel types." - ::= { astChanTypeEntry 1 } - -astChanTypeName OBJECT-TYPE - SYNTAX DisplayString - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Unique name of the technology we are describing." - ::= { astChanTypeEntry 2 } - -astChanTypeDesc OBJECT-TYPE - SYNTAX DisplayString - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Description of the channel type (technology)." - ::= { astChanTypeEntry 3 } - -astChanTypeDeviceState OBJECT-TYPE - SYNTAX TruthValue - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Whether the current technology can hold device states." - ::= { astChanTypeEntry 4 } - -astChanTypeIndications OBJECT-TYPE - SYNTAX TruthValue - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Whether the current technology supports progress indication." - ::= { astChanTypeEntry 5 } - -astChanTypeTransfer OBJECT-TYPE - SYNTAX TruthValue - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Whether the current technology supports transfers, where - Asterisk can get out from inbetween two bridged channels." - ::= { astChanTypeEntry 6 } - -astChanTypeChannels OBJECT-TYPE - SYNTAX Gauge32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Number of active channels using the current technology." - ::= { astChanTypeEntry 7 } - -astChanScalars OBJECT IDENTIFIER ::= { asteriskChannels 5 } - -astNumChanBridge OBJECT-TYPE - SYNTAX Gauge32 - MAX-ACCESS read-only - STATUS current - DESCRIPTION - "Number of channels currently in a bridged state." - ::= { astChanScalars 1 } - -END diff --git a/doc/backtrace.txt b/doc/backtrace.txt deleted file mode 100644 index cf2518de0..000000000 --- a/doc/backtrace.txt +++ /dev/null @@ -1,277 +0,0 @@ -=============================================================================== -=== -=== Collecting Backtrace Information -=== -=== Last updated: 2010-04-12 -=============================================================================== - -This document is intended to provide information on how to obtain the -backtraces required on the asterisk bug tracker, available at -https://issues.asterisk.org. - -------------------------------------------------------------------------------- ---- Overview -------------------------------------------------------------------------------- - -The backtrace information is required by developers to help fix problem with -bugs of any kind. Backtraces provide information about what was wrong when a -program crashed; in our case, Asterisk. - -------------------------------------------------------------------------------- ---- Preparing Asterisk To Produce Core Files On Crash -------------------------------------------------------------------------------- - -First of all, when you start Asterisk, you MUST start it with option --g. This tells Asterisk to produce a core file if it crashes. - -If you start Asterisk with the safe_asterisk script, it automatically -starts using the option -g. - -If you're not sure if Asterisk is running with the -g option, type the -following command in your shell: - -debian:/tmp# ps aux | grep asterisk -root 17832 0.0 1.2 2348 788 pts/1 S Aug12 0:00 /bin/sh /usr/sbin/safe_asterisk -root 26686 0.0 2.8 15544 1744 pts/1 S Aug13 0:02 asterisk -vvvg -c -[...] - -The interesting information is located in the last column. - -Second, your copy of Asterisk must have been built without -optimization or the backtrace will be (nearly) unusable. This can be -done by selecting the 'DONT_OPTIMIZE' option in the Compiler Flags -submenu in the 'make menuselect' tree before building Asterisk. - -Running a production server with DONT_OPTIMIZE is generally safe. -You'll notice the binary files may be a bit larger, but in terms of -Asterisk performance, and impact should be negligible. - -After Asterisk crashes, a core file will be "dumped" in your /tmp/ -directory. To make sure it's really there, you can just type the -following command in your shell: - -debian:/tmp# ls -l /tmp/core.* --rw------- 1 root root 10592256 Aug 12 19:40 /tmp/core.26252 --rw------- 1 root root 9924608 Aug 12 20:12 /tmp/core.26340 --rw------- 1 root root 10862592 Aug 12 20:14 /tmp/core.26374 --rw------- 1 root root 9105408 Aug 12 20:19 /tmp/core.26426 --rw------- 1 root root 9441280 Aug 12 20:20 /tmp/core.26462 --rw------- 1 root root 8331264 Aug 13 00:32 /tmp/core.26647 -debian:/tmp# - -In the event that there are multiple core files present (as in the -above example), it is important to look at the file timestamps in -order to determine which one you really intend to look at. - -------------------------------------------------------------------------------- ---- Getting Information After A Crash -------------------------------------------------------------------------------- - -There are two kind of backtraces (aka 'bt') which are useful: bt and bt full. - -Now that we've verified the core file has been written to disk, the final part -is to extract 'bt' from the core file. Core files are pretty big, don't be -scared, it's normal. - -****************************************************************************** -*** NOTE: Don't attach core files on the bug tracker as they are only useful * -*** on the machine they were generated on. We only need the output of * -*** the 'bt' and 'bt full.' * -****************************************************************************** - -For extraction, we use a really nice tool, called gdb. To verify that -you have gdb installed on your system: - -debian:/tmp# gdb -v -GNU gdb 6.3-debian -Copyright 2004 Free Software Foundation, Inc. -GDB is free software, covered by the GNU General Public License, and you are -welcome to change it and/or distribute copies of it under certain conditions. -Type "show copying" to see the conditions. -There is absolutely no warranty for GDB. Type "show warranty" for details. -This GDB was configured as "i386-linux". -debian:/tmp# - -If you don't have gdb installed, go install gdb. You should be able to install -using something like: apt-get install gdb --or-- yum install gdb - -Now load the core file in gdb with the following command. This will also save -the output of gdb to the /tmp/backtract.txt file. - -# gdb -se "asterisk" -c /tmp/core.26252 | tee /tmp/backtrace.txt - -****************************************************************************** -*** TIP! -*** Just run the following command to get the output into the -*** backtrace.txt file, ready for uploading to the issue tracker. Be sure -*** to change the name of the core file to your actual core dump file: -*** -*** gdb -se "asterisk" -ex "bt full" -ex "thread apply all bt" --batch -c /tmp/core.26252 > /tmp/backtrace.txt -*** -****************************************************************************** - - -[...] -(You would see a lot of output here.) -[...] -Reading symbols from /usr/lib/asterisk/modules/app_externalivr.so...done. -Loaded symbols for /usr/lib/asterisk/modules/app_externalivr.so -#0 0x29b45d7e in ?? () -(gdb) - -In order to make extracting the gdb output easier, you may wish to -turn on logging using "set logging on". This command will save all -output to the default file of gdb.txt, which in the end can be -uploaded as an attachment to the bug tracker. - -Now at the gdb prompt, type: bt -You would see output similar to: - -(gdb) bt -#0 0x29b45d7e in ?? () -#1 0x08180bf8 in ?? () -#2 0xbcdffa58 in ?? () -#3 0x08180bf8 in ?? () -#4 0xbcdffa60 in ?? () -#5 0x08180bf8 in ?? () -#6 0x180bf894 in ?? () -#7 0x0bf80008 in ?? () -#8 0x180b0818 in ?? () -#9 0x08068008 in ast_stopstream (tmp=0x40758d38) at file.c:180 -#10 0x000000a0 in ?? () -#11 0x000000a0 in ?? () -#12 0x00000000 in ?? () -#13 0x407513c3 in confcall_careful_stream (conf=0x8180bf8, filename=0x8181de8 "DAHDI/pseudo-1324221520") at app_meetme.c:262 -#14 0x40751332 in streamconfthread (args=0x8180bf8) at app_meetme.c:1965 -#15 0xbcdffbe0 in ?? () -#16 0x40028e51 in pthread_start_thread () from /lib/libpthread.so.0 -#17 0x401ec92a in clone () from /lib/libc.so.6 -(gdb) - - -The bt's output is the information that we need on the bug tracker. - -Now do a bt full as follows: - -(gdb) bt full -#0 0x29b45d7e in ?? () -No symbol table info available. -#1 0x08180bf8 in ?? () -No symbol table info available. -#2 0xbcdffa58 in ?? () -No symbol table info available. -#3 0x08180bf8 in ?? () -No symbol table info available. -#4 0xbcdffa60 in ?? () -No symbol table info available. -#5 0x08180bf8 in ?? () -No symbol table info available. -#6 0x180bf894 in ?? () -No symbol table info available. -#7 0x0bf80008 in ?? () -No symbol table info available. -#8 0x180b0818 in ?? () -No symbol table info available. -#9 0x08068008 in ast_stopstream (tmp=0x40758d38) at file.c:180 -No locals. -#10 0x000000a0 in ?? () -No symbol table info available. -#11 0x000000a0 in ?? () -No symbol table info available. -#12 0x00000000 in ?? () -No symbol table info available. -#13 0x407513c3 in confcall_careful_stream (conf=0x8180bf8, filename=0x8181de8 "DAHDI/pseudo-1324221520") at app_meetme.c:262 - f = (struct ast_frame *) 0x8180bf8 - trans = (struct ast_trans_pvt *) 0x0 -#14 0x40751332 in streamconfthread (args=0x8180bf8) at app_meetme.c:1965 -No locals. -#15 0xbcdffbe0 in ?? () -No symbol table info available. -#16 0x40028e51 in pthread_start_thread () from /lib/libpthread.so.0 -No symbol table info available. -#17 0x401ec92a in clone () from /lib/libc.so.6 -No symbol table info available. -(gdb) - -The final "extraction" would be to know all traces by all threads. Even if -Asterisk runs on the same thread for each call, it could have created some new -threads. - -To make sure we have the correct information, just do: -(gdb) thread apply all bt - -Thread 1 (process 26252): -#0 0x29b45d7e in ?? () -#1 0x08180bf8 in ?? () -#2 0xbcdffa58 in ?? () -#3 0x08180bf8 in ?? () -#4 0xbcdffa60 in ?? () -#5 0x08180bf8 in ?? () -#6 0x180bf894 in ?? () -#7 0x0bf80008 in ?? () -#8 0x180b0818 in ?? () -#9 0x08068008 in ast_stopstream (tmp=0x40758d38) at file.c:180 -#10 0x000000a0 in ?? () -#11 0x000000a0 in ?? () -#12 0x00000000 in ?? () -#13 0x407513c3 in confcall_careful_stream (conf=0x8180bf8, filename=0x8181de8 "DAHDI/pseudo-1324221520") at app_meetme.c:262 -#14 0x40751332 in streamconfthread (args=0x8180bf8) at app_meetme.c:1965 -#15 0xbcdffbe0 in ?? () -#16 0x40028e51 in pthread_start_thread () from /lib/libpthread.so.0 -#17 0x401ec92a in clone () from /lib/libc.so.6 -(gdb) - - -That output tells us crucial information about each thread. - -------------------------------------------------------------------------------- ---- Getting Information For A Deadlock -------------------------------------------------------------------------------- - -Whenever supplying information about a deadlock (i.e. when you run the -'core show locks' command on the Asterisk console), it is useful to also have -additional information about the threads. We can generate this information by -attaching to a running Asterisk process and gathering that information. - -You can easily attach to a running Asterisk process, gather the output required -and then detach from the process all in a single step. Execute the following -command and upload the resulting backtrace-threads.txt file to the Asterisk -issue tracker: - - gdb -ex "thread apply all bt" --batch /usr/sbin/asterisk `pidof asterisk` > /tmp/backtrace-threads.txt - -Note that this gathers information from the running Asterisk process, so you -want to make sure you run this command immediately before or after gathering -the output of 'core show locks'. You can gather that information by running the -following command: - - asterisk -rx "core show locks" > /tmp/core-show-locks.txt - -------------------------------------------------------------------------------- ---- Verify Your Backtraces -------------------------------------------------------------------------------- - -Before uploading your backtraces to the issue tracker, you should double check -to make sure the data you have is of use to the developers. Check your -backtrace files to make sure you're not seeing several of the following: - - - -If you are, then you likely haven't compiled with DONT_OPTIMIZE. The impact of -DONT_OPTIMIZE is negligible on most systems. Be sure you've enabled the -DONT_OPTIMIZE flag within the Compiler Flags section of menuselect. After -doing so, be sure to run 'make install' and restart Asterisk. - -------------------------------------------------------------------------------- ---- Uploading Your Information To The Issue Tracker -------------------------------------------------------------------------------- - -You're now ready to upload your files to the Asterisk issue tracker (located at -https://issues.asterisk.org). - -****************************************************************************** -*** NOTE: Please ATTACH your output! DO NOT paste it as a note! * -****************************************************************************** - -If you have questions or comments regarding this documentation, feel free to -pass by the #asterisk-bugs channel on irc.freenode.net. diff --git a/doc/building_queues.txt b/doc/building_queues.txt deleted file mode 100644 index a5da7a2f8..000000000 --- a/doc/building_queues.txt +++ /dev/null @@ -1,823 +0,0 @@ -================= - Building Queues -================= - -Written by: Leif Madsen -Initial version: 2010-01-14 - -In this article, we'll look at setting up a pair of queues in Asterisk called -'sales' and 'support'. These queues can be logged into by queue members, and -those members will also have the ability to pause and unpause themselves. - -All configuration will be done in flat files on the system in order to maintain -simplicity in configuration. - -Note that this documentation is based on Asterisk 1.6.2, and this is just one -approach to creating queues and the dialplan logic. You may create a better way, -and in that case, I would encourage you to submit it to the Asterisk issue -tracker at http://issues.asterisk.org for inclusion in Asterisk. - -------------------------------------- -| Adding SIP Devices to Your Server | -------------------------------------- - -The first thing we want to do is register a couple of SIP devices to our server. -These devices will be our agents that can login and out of the queues we'll -create later. Our naming convention will be to use MAC addresses as we want to -abstract the concepts of user (agent), device, and extension from each other. - -In sip.conf, we add the following to the bottom of our file: - -sip.conf --------- - -[std-device](!) -type=peer -context=devices -host=dynamic -secret=s3CuR#p@s5 -dtmfmode=rfc2833 -disallow=all -allow=ulaw - -[0004f2040001](std-device) - -[0004f2040002](std-device) - - - -What we're doing here is creating a [std-device] template and applying it to -a pair of peers that we'll register as 0004f2040001 and 0004f2040002; our -devices. - -Then our devices can register to Asterisk. In my case I have a hard phone and -a soft phone registered. I can verify their connectivity by running 'sip show -peers'. - -*CLI> sip show peers -Name/username Host Dyn Nat ACL Port Status -0004f2040001/0004f2040001 192.168.128.145 D 5060 Unmonitored -0004f2040002/0004f2040002 192.168.128.126 D 5060 Unmonitored -2 sip peers [Monitored: 0 online, 0 offline Unmonitored: 2 online, 0 offline] - - - ----------------------------- -| Configuring Device State | ----------------------------- - -Next, we need to configure our system to track the state of the devices. We do -this by defining a 'hint' in the dialplan which creates the ability for a device -subscription to be retained in memory. By default we can see there are no hints -registered in our system by running the 'core show hints' command. - -*CLI> core show hints -There are no registered dialplan hint - - -We need to add the devices we're going to track to the extensions.conf file -under the [default] context which is the default configuration in sip.conf, -however we can change this to any context we want with the 'subscribecontext' -option. - -Add the following lines to extensions.conf: - -[default] -exten => 0004f2040001,hint,SIP/0004f2040001 -exten => 0004f2040002,hint,SIP/0004f2040002 - -Then perform a 'dialplan reload' in order to reload the dialplan. - -After reloading our dialplan, you can see the status of the devices with 'core -show hints' again. - - -*CLI> core show hints - - -= Registered Asterisk Dial Plan Hints =- - 0004f2040002@default : SIP/0004f2040002 State:Idle Watchers 0 - 0004f2040001@default : SIP/0004f2040001 State:Idle Watchers 0 ----------------- -- 2 hints registered - - -At this point, create an extension that you can dial that will play a prompt -that is long enough for you to go back to the Asterisk console to check the -state of your device while it is in use. - -To do this, add the 555 extension to the [devices] context and make it playback -the tt-monkeys file. - - -extensions.conf ---------------- - -[devices] -exten => 555,1,Playback(tt-monkeys) - - -Dial that extension and then check the state of your device on the console. - -*CLI> == Using SIP RTP CoS mark 5 - -- Executing [555@devices:1] Playback("SIP/0004f2040001-00000001", "tt-monkeys") in new stack - -- Playing 'tt-monkeys.slin' (language 'en') - -*CLI> core show hints - - -= Registered Asterisk Dial Plan Hints =- - 0004f2040002@default : SIP/0004f2040002 State:Idle Watchers 0 - 0004f2040001@default : SIP/0004f2040001 State:Idle Watchers 0 ----------------- -- 2 hints registered - -Aha, we're not getting the device state correctly. There must be something else -we need to configure. - -In sip.conf, we need to enable 'callcounter' in order to activate the ability -for Asterisk to monitor whether the device is in use or not. In versions prior -to 1.6.0 we needed to use 'call-limit' for this functionality, but call-limit -is now deprecated and is no longer necessary. - -So, in sip.conf, in our [std-device] template, we need to add the callcounter -option. - -sip.conf --------- - -[std-device](!) -type=peer -context=devices -host=dynamic -secret=s3CuR#p@s5 -dtmfmode=rfc2833 -disallow=all -allow=ulaw -callcounter=yes ; <-- add this - - -Then reload chan_sip with 'sip reload' and perform our 555 test again. Dial 555 -and then check the device state with 'core show hints'. - -*CLI> == Using SIP RTP CoS mark 5 - -- Executing [555@devices:1] Playback("SIP/0004f2040001-00000002", "tt-monkeys") in new stack - -- Playing 'tt-monkeys.slin' (language 'en') - -*CLI> core show hints - - -= Registered Asterisk Dial Plan Hints =- - 0004f2040002@default : SIP/0004f2040002 State:Idle Watchers 0 - 0004f2040001@default : SIP/0004f2040001 State:InUse Watchers 0 ----------------- -- 2 hints registered - - -Note that now we have the correct device state when extension 555 is dialed, -showing that our device is InUse after dialing extension 555. This is important -when creating queues, otherwise our queue members would get multiple calls from -the queues. - ------------------------------ -| Adding Queues to Asterisk | ------------------------------ - -The next step is to add a couple of queues to Asterisk that we can assign queue -members into. For now we'll work with two queues; sales and support. Lets create -those queues now in queues.conf. - -We'll leave the default settings that are shipped with queues.conf.sample in the -[general] section of queues.conf. See the queues.conf.sample file for more -information about each of the available options. - -queues.conf ------------ - -[general] -persistantmembers=yes -autofill=yes -monitor-type=MixMonitor -shared_lastcall=no - - -We can then define a [queue_template] that we'll assign to each of the queues -we create. These definitions can be overridden by each queue individually if you -reassign them under the [sales] or [support] headers. So under the [general] -section of your queues.conf file, add the following. - - -queues.conf ----------- - -[queue_template](!) -musicclass=default ; play [default] music -strategy=rrmemory ; use the Round Robin Memory strategy -joinempty=yes ; join the queue when no members available -leavewhenempty=no ; don't leave the queue no members available -ringinuse=no ; don't ring members when already InUse - -[sales](queue_template) -; Sales queue - -[support](queue_template) -; Support queue - - - -After defining our queues, lets reload our app_queue.so module. - - -*CLI> module reload app_queue.so - -- Reloading module 'app_queue.so' (True Call Queueing) - - == Parsing '/etc/asterisk/queues.conf': == Found - - -Then verify our queues loaded with 'queue show'. - - -*CLI> queue show -support has 0 calls (max unlimited) in 'rrmemory' strategy (0s holdtime, 0s talktime), W:0, C:0, A:0, SL:0.0% within 0s - No Members - No Callers - -sales has 0 calls (max unlimited) in 'rrmemory' strategy (0s holdtime, 0s talktime), W:0, C:0, A:0, SL:0.0% within 0s - No Members - No Callers - - - ------------------------- -| Adding Queue Members | ------------------------- - -You'll notice that we have no queue members available to take calls from the -queues. We can add queue members from the Asterisk CLI with the 'queue add -member' command. - -This is the format of the 'queue add member' command: - -Usage: queue add member to [[[penalty ] as ] state_interface ] - Add a channel to a queue with optionally: a penalty, membername and a state_interface - -The penalty, membername, and state_interface are all optional values. Special -attention should be brought to the 'state_interface' option for a member though. -The reason for state_interface is that if you're using a channel that does not -have device state itself (for example, if you were using the Local channel to -deliver a call to an end point) then you could assign the device state of a SIP -device to the pseudo channel. This allows the state of a SIP device to be -applied to the Local channel for correct device state information. - -Lets add our device located at SIP/0004f2040001 - -*CLI> queue add member SIP/0004f2040001 to sales -Added interface 'SIP/0004f2040001' to queue 'sales' - -Then lets verify our member was indeed added. - -*CLI> queue show sales -sales has 0 calls (max unlimited) in 'rrmemory' strategy (0s holdtime, 0s talktime), W:0, C:0, A:0, SL:0.0% within 0s - Members: - SIP/0004f2040001 (dynamic) (Not in use) has taken no calls yet - No Callers - -Now, if we dial our 555 extension, we should see that our member becomes InUse -within the queue. - -*CLI> == Using SIP RTP CoS mark 5 - -- Executing [555@devices:1] Playback("SIP/0004f2040001-00000001", "tt-monkeys") in new stack - -- Playing 'tt-monkeys.slin' (language 'en') - - -*CLI> queue show sales -sales has 0 calls (max unlimited) in 'rrmemory' strategy (0s holdtime, 0s talktime), W:0, C:0, A:0, SL:0.0% within 0s - Members: - SIP/0004f2040001 (dynamic) (In use) has taken no calls yet - No Callers - -We can also remove our members from the queue using the 'queue remove' CLI -command. - -*CLI> queue remove member SIP/0004f2040001 from sales -Removed interface 'SIP/0004f2040001' from queue 'sales' - -Because we don't want to have to add queue members manually from the CLI, we -should create a method that allows queue members to login and out from their -devices. We'll do that in the next section. - -But first, lets add an extension to our dialplan in order to permit people to -dial into our queues so calls can be delivered to our queue members. - -extensions.conf ---------------- - -[devices] -exten => 555,1,Playback(tt-monkeys) - -exten => 100,1,Queue(sales) - -exten => 101,1,Queue(support) - - -Then reload the dialplan, and try calling extension 100 from SIP/0004f2040002, -which is the device we have not logged into the queue. - -*CLI> dialplan reload - -And now we call the queue at extension 100 which will ring our device at -SIP/0004f2040001. - -*CLI> == Using SIP RTP CoS mark 5 - -- Executing [100@devices:1] Queue("SIP/0004f2040002-00000005", "sales") in new stack - -- Started music on hold, class 'default', on SIP/0004f2040002-00000005 - == Using SIP RTP CoS mark 5 - -- SIP/0004f2040001-00000006 is ringing - - -We can see the device state has changed to Ringing while the device is ringing. - -*CLI> queue show sales -sales has 1 calls (max unlimited) in 'rrmemory' strategy (2s holdtime, 3s talktime), W:0, C:1, A:1, SL:0.0% within 0s - Members: - SIP/0004f2040001 (dynamic) (Ringing) has taken 1 calls (last was 14 secs ago) - Callers: - 1. SIP/0004f2040002-00000005 (wait: 0:03, prio: 0) - - -Our queue member then answers the phone. - -*CLI> -- SIP/0004f2040001-00000006 answered SIP/0004f2040002-00000005 - -- Stopped music on hold on SIP/0004f2040002-00000005 - -- Native bridging SIP/0004f2040002-00000005 and SIP/0004f2040001-00000006 - - -And we can see the queue member is now in use. - -*CLI> queue show sales -sales has 0 calls (max unlimited) in 'rrmemory' strategy (3s holdtime, 3s talktime), W:0, C:1, A:1, SL:0.0% within 0s - Members: - SIP/0004f2040001 (dynamic) (In use) has taken 1 calls (last was 22 secs ago) - No Callers - - -Then the call is hung up. - -*CLI> == Spawn extension (devices, 100, 1) exited non-zero on 'SIP/0004f2040002-00000005' - - -And we see that our queue member is available to take another call. - -*CLI> queue show sales -sales has 0 calls (max unlimited) in 'rrmemory' strategy (3s holdtime, 4s talktime), W:0, C:2, A:1, SL:0.0% within 0s - Members: - SIP/0004f2040001 (dynamic) (Not in use) has taken 2 calls (last was 6 secs ago) - No Callers - --------------------------------- -| Logging In and Out of Queues | --------------------------------- - -In this section we'll show how to use the AddQueueMember() and -RemoveQueueMember() dialplan applications to login and out of queues. For more -information about the available options to AddQueueMember() and -RemoveQueueMember() use the 'core show application ' command from the CLI. - -The following bit of dialplan is a bit long, but stick with it, and you'll see -that it isn't really all that bad. The gist of the dialplan is that it will -check to see if the active user (the device that is dialing the extension) is -currently logged into the queue extension that has been requested, and if logged -in, then will log them out; if not logged in, then they will be logged into the -queue. - -We've updated the two lines we added in the previous section that allowed us to -dial the sales and support queues. We've abstracted this out a bit in order to -make it easier to add new queues in the future. This is done by adding the queue -names to a global variable, then utilizing the extension number dialed to look -up the queue name. - -So we replace extension 100 and 101 with the following dialplan. - -; Call any of the queues we've defined in the [globals] section. -exten => _1XX,1,Verbose(2,Call queue as configured in the QUEUE_${EXTEN} global variable) -exten => _1XX,n,Set(thisQueue=${GLOBAL(QUEUE_${EXTEN})}) -exten => _1XX,n,GotoIf($["${thisQueue}" = ""]?invalid_queue,1) -exten => _1XX,n,Verbose(2, --> Entering the ${thisQueue} queue) -exten => _1XX,n,Queue(${thisQueue}) -exten => _1XX,n,Hangup() - -exten => invalid_queue,1,Verbose(2,Attempted to enter invalid queue) -exten => invalid_queue,n,Playback(silence/1&invalid) -exten => invalid_queue,n,Hangup() - -The [globals] section contains the following two global variables. - -[globals] -QUEUE_100=sales -QUEUE_101=support - -So when we dial extension 100, it matches our pattern _1XX. The number we dialed -(100) is then retrievable via ${EXTEN} and we can get the name of queue 100 -(sales) from the global variable QUEUE_100. We then assign it to the channel -variable thisQueue so it is easier to work with in our dialplan. - -exten => _1XX,n,Set(thisQueue=${GLOBAL(QUEUE_${EXTEN})}) - -We then check to see if we've gotten a value back from the global variable which -would indicate whether the queue was valid or not. - -exten => _1XX,n,GotoIf($["${thisQueue}" = ""]?invalid_queue,1) - -If ${thisQueue} returns nothing, then we Goto the invalid_queue extension and -playback the 'invalid' file. - -We could alternatively limit our pattern match to only extension 100 and 101 -with the _10[0-1] pattern instead. - -Lets move into the nitty-gritty section and show how we can login and logout our -devices to the pair of queues we've created. - -First, we create a pattern match that takes star (*) plus the queue number -that we want to login or logout of. So to login/out of the sales queue (100) we -would dial *100. We use the same extension for logging in and out. - -; Extension *100 or *101 will login/logout a queue member from sales or support queues respectively. -exten => _*10[0-1],1,Set(xtn=${EXTEN:1}) ; save ${EXTEN} with * chopped off to ${xtn} -exten => _*10[0-1],n,Goto(queueLoginLogout,member_check,1) ; check if already logged into a queue - -We save the value of ${EXTEN:1} to the 'xtn' channel variable so we don't need -to keep typing the complicated pattern match. - -Now we move into the meat of our login/out dialplan inside the -[queueLoginLogout] context. - -The first section is initializing some variables that we need throughout the -member_check extension such as the name of the queue, the members currently -logged into the queue, and the current device peer name (i.e. SIP/0004f2040001). - - - -; ### Login or Logout a Queue Member -[queueLoginLogout] -exten => member_check,1,Verbose(2,Logging queue member in or out of the request queue) -exten => member_check,n,Set(thisQueue=${GLOBAL(QUEUE_${xtn})}) ; assign queue name to a variable -exten => member_check,n,Set(queueMembers=${QUEUE_MEMBER_LIST(${thisQueue})}) ; assign list of logged in members of thisQueue to - ; a variable (comma separated) -exten => member_check,n,Set(thisActiveMember=SIP/${CHANNEL(peername)}) ; initialize 'thisActiveMember' as current device - -exten => member_check,n,GotoIf($["${queueMembers}" = ""]?q_login,1) ; short circuit to logging in if we don't have - ; any members logged into this queue - - - -At this point if there are no members currently logged into our sales queue, -we then short-circuit our dialplan to go to the 'q_login' extension since there -is no point in wasting cycles searching to see if we're already logged in. - -The next step is to finish initializing some values we need within the While() -loop that we'll use to check if we're already logged into the queue. We set -our ${field} variable to 1, which will be used as the field number offset in -the CUT() function. - - -; Initialize some values we'll use in the While() loop -exten => member_check,n,Set(field=1) ; start our field counter at one -exten => member_check,n,Set(logged_in=0) ; initialize 'logged_in' to "not logged in" -exten => member_check,n,Set(thisQueueMember=${CUT(queueMembers,\,,${field})}) ; initialize 'thisQueueMember' with the value in the - ; first field of the comma-separated list - - -Now we get to enter our While() loop to determine if we're already logged in. - - -; Enter our loop to check if our member is already logged into this queue -exten => member_check,n,While($[${EXISTS(${thisQueueMember})}]) ; while we have a queue member... - - -This is where we check to see if the member at this position of the list is the -same as the device we're calling from. If it doesn't match, then we go to the -'check_next' priority label (where we increase our ${field} counter variable). -If it does match, then we continue on in the dialplan. - -exten => member_check,n,GotoIf($["${thisQueueMember}" != "${thisActiveMember}"]?check_next) ; if 'thisQueueMember' is not the - ; same as our active peer, then - ; check the next in the list of - ; logged in queue members - -If we continued on in the dialplan, then we set the ${logged_in} channel -variable to '1' which represents we're already logged into this queue. We then -exit the While() loop with the ExitWhile() dialplan application. - -exten => member_check,n,Set(logged_in=1) ; if we got here, set as logged in -exten => member_check,n,ExitWhile() ; then exit our loop - - - -If we didn't match this peer name in the list, then we increase our ${field} -counter variable by one, update the ${thisQueueMember} channel variable and then -move back to the top of the loop for another round of checks. - -exten => member_check,n(check_next),Set(field=$[${field} + 1]) ; if we got here, increase counter -exten => member_check,n,Set(thisQueueMember=${CUT(queueMembers,\,,${field})}) ; get next member in the list -exten => member_check,n,EndWhile() ; ...end of our loop - - -And once we exit our loop, we determine whether we need to log our device in -or out of the queue. - -; if not logged in, then login to this queue, otherwise, logout -exten => member_check,n,GotoIf($[${logged_in} = 0]?q_login,1:q_logout,1) ; if not logged in, then login, otherwise, logout - - - -The following two extensions are used to either log the device in or out of the -queue. We use the AddQueueMember() and RemovQueueMember() applications to login -or logout the device from the queue. - -The first two arguments for AddQueueMember() and RemoveQueueMember() are 'queue' -and 'device'. There are additional arguments we can pass, and you can check -those out with 'core show application AddQueueMember' and 'core show -application RemoveQueueMember()'. - -; ### Login queue member ### -exten => q_login,1,Verbose(2,Logging ${thisActiveMember} into the ${thisQueue} queue) -exten => q_login,n,AddQueueMember(${thisQueue},${thisActiveMember}) ; login our active device to the queue - ; requested -exten => q_login,n,Playback(silence/1) ; answer the channel by playing one second of silence - -; If the member was added to the queue successfully, then playback "Agent logged in", otherwise, state an error occurred -exten => q_login,n,ExecIf($["${AQMSTATUS}" = "ADDED"]?Playback(agent-loginok):Playback(an-error-has-occurred)) -exten => q_login,n,Hangup() - - -; ### Logout queue member ### -exten => q_logout,1,Verbose(2,Logging ${thisActiveMember} out of ${thisQueue} queue) -exten => q_logout,n,RemoveQueueMember(${thisQueue},${thisActiveMember}) -exten => q_logout,n,Playback(silence/1) -exten => q_logout,n,ExecIf($["${RQMSTATUS}" = "REMOVED"]?Playback(agent-loggedoff):Playback(an-error-has-occurred)) -exten => q_logout,n,Hangup() - - -And that's it! Give it a shot and you should see console output similar to the -following which will login and logout your queue members to the queues you've -configured. - -You can see there are already a couple of queue members logged into the sales -queue. - -*CLI> queue show sales -sales has 0 calls (max unlimited) in 'rrmemory' strategy (3s holdtime, 4s talktime), W:0, C:2, A:1, SL:0.0% within 0s - Members: - SIP/0004f2040001 (dynamic) (Not in use) has taken no calls yet - SIP/0004f2040002 (dynamic) (Not in use) has taken no calls yet - No Callers - - -Then we dial *100 to logout the active device from the sales queue. - -*CLI> == Using SIP RTP CoS mark 5 - -- Executing [*100@devices:1] Set("SIP/0004f2040001-00000012", "xtn=100") in new stack - -- Executing [*100@devices:2] Goto("SIP/0004f2040001-00000012", "queueLoginLogout,member_check,1") in new stack - -- Goto (queueLoginLogout,member_check,1) - -- Executing [member_check@queueLoginLogout:1] Verbose("SIP/0004f2040001-00000012", "2,Logging queue member in or out of the request queue") in new stack - == Logging queue member in or out of the request queue - -- Executing [member_check@queueLoginLogout:2] Set("SIP/0004f2040001-00000012", "thisQueue=sales") in new stack - -- Executing [member_check@queueLoginLogout:3] Set("SIP/0004f2040001-00000012", "queueMembers=SIP/0004f2040001,SIP/0004f2040002") in new stack - -- Executing [member_check@queueLoginLogout:4] Set("SIP/0004f2040001-00000012", "thisActiveMember=SIP/0004f2040001") in new stack - -- Executing [member_check@queueLoginLogout:5] GotoIf("SIP/0004f2040001-00000012", "0?q_login,1") in new stack - -- Executing [member_check@queueLoginLogout:6] Set("SIP/0004f2040001-00000012", "field=1") in new stack - -- Executing [member_check@queueLoginLogout:7] Set("SIP/0004f2040001-00000012", "logged_in=0") in new stack - -- Executing [member_check@queueLoginLogout:8] Set("SIP/0004f2040001-00000012", "thisQueueMember=SIP/0004f2040001") in new stack - -- Executing [member_check@queueLoginLogout:9] While("SIP/0004f2040001-00000012", "1") in new stack - -- Executing [member_check@queueLoginLogout:10] GotoIf("SIP/0004f2040001-00000012", "0?check_next") in new stack - -- Executing [member_check@queueLoginLogout:11] Set("SIP/0004f2040001-00000012", "logged_in=1") in new stack - -- Executing [member_check@queueLoginLogout:12] ExitWhile("SIP/0004f2040001-00000012", "") in new stack - -- Jumping to priority 15 - -- Executing [member_check@queueLoginLogout:16] GotoIf("SIP/0004f2040001-00000012", "0?q_login,1:q_logout,1") in new stack - -- Goto (queueLoginLogout,q_logout,1) - -- Executing [q_logout@queueLoginLogout:1] Verbose("SIP/0004f2040001-00000012", "2,Logging SIP/0004f2040001 out of sales queue") in new stack - == Logging SIP/0004f2040001 out of sales queue - -- Executing [q_logout@queueLoginLogout:2] RemoveQueueMember("SIP/0004f2040001-00000012", "sales,SIP/0004f2040001") in new stack -[Nov 12 12:08:51] NOTICE[11582]: app_queue.c:4842 rqm_exec: Removed interface 'SIP/0004f2040001' from queue 'sales' - -- Executing [q_logout@queueLoginLogout:3] Playback("SIP/0004f2040001-00000012", "silence/1") in new stack - -- Playing 'silence/1.slin' (language 'en') - -- Executing [q_logout@queueLoginLogout:4] ExecIf("SIP/0004f2040001-00000012", "1?Playback(agent-loggedoff):Playback(an-error-has-occurred)") in new stack - -- Playing 'agent-loggedoff.slin' (language 'en') - -- Executing [q_logout@queueLoginLogout:5] Hangup("SIP/0004f2040001-00000012", "") in new stack - == Spawn extension (queueLoginLogout, q_logout, 5) exited non-zero on 'SIP/0004f2040001-00000012' - - -And we can see that the device we loggd out by running 'queue show sales'. - -*CLI> queue show sales -sales has 0 calls (max unlimited) in 'rrmemory' strategy (3s holdtime, 4s talktime), W:0, C:2, A:1, SL:0.0% within 0s - Members: - SIP/0004f2040002 (dynamic) (Not in use) has taken no calls yet - No Callers - - -------------------------------------------- -| Pausing and Unpausing Members of Queues | -------------------------------------------- - -Once we have our queue members logged in, it is inevitable that they will want -to pause themselves during breaks, and other short periods of inactivity. To do -this we can utilize the 'queue pause' and 'queue unpause' CLI commands. - -We have two devices logged into the sales queue as we can see with the 'queue -show sales' CLI command. - -*CLI> queue show sales -sales has 0 calls (max unlimited) in 'rrmemory' strategy (0s holdtime, 0s talktime), W:0, C:0, A:0, SL:0.0% within 0s - Members: - SIP/0004f2040002 (dynamic) (Not in use) has taken no calls yet - SIP/0004f2040001 (dynamic) (Not in use) has taken no calls yet - No Callers - - -We can then pause our devices with 'queue pause' which has the following format. - -Usage: queue {pause|unpause} member [queue [reason ]] - Pause or unpause a queue member. Not specifying a particular queue - will pause or unpause a member across all queues to which the member - belongs. - -Lets pause device 0004f2040001 in the sales queue by executing the following. - -*CLI> queue pause member SIP/0004f2040001 queue sales -paused interface 'SIP/0004f2040001' in queue 'sales' for reason 'lunch' - - -And we can see they are paused with 'queue show sales'. - -*CLI> queue show sales -sales has 0 calls (max unlimited) in 'rrmemory' strategy (0s holdtime, 0s talktime), W:0, C:0, A:0, SL:0.0% within 0s - Members: - SIP/0004f2040002 (dynamic) (Not in use) has taken no calls yet - SIP/0004f2040001 (dynamic) (paused) (Not in use) has taken no calls yet - No Callers - -At this point the queue member will no longer receive calls from the system. We -can unpause them with the CLI command 'queue unpause member'. - -*CLI> queue unpause member SIP/0004f2040001 queue sales -unpaused interface 'SIP/0004f2040001' in queue 'sales' - -And if you don't specify a queue, it will pause or unpause from all queues. - -*CLI> queue pause member SIP/0004f2040001 -paused interface 'SIP/0004f2040001' - - -Of course we want to allow the agents to pause and unpause themselves from their -devices, so we need to create an extension and some dialplan logic for that to -happen. - -Below we've created the pattern patch _*0[01]! which will match on *00 and *01, -and will *also* match with zero or more digits following it, such as the queue -extension number. - -So if we want to pause ourselves in all queues, we can dial *00; unpausing can -be done with *01. But if our agents just need to pause or unpause themselves -from a single queue, then we will also accept *00100 to pause in queue 100 -(sales), or we can unpause ourselves from sales with *01100. - - -extensions.conf ---------------- - -; Allow queue members to pause and unpause themselves from all queues, or an individual queue. -; -; _*0[01]! pattern match will match on *00 and *01 plus 0 or more digits. -exten => _*0[01]!,1,Verbose(2,Pausing or unpausing queue member from one or more queues) -exten => _*0[01]!,n,Set(xtn=${EXTEN:3}) ; save the queue extension to 'xtn' -exten => _*0[01]!,n,Set(thisQueue=${GLOBAL(QUEUE_${xtn})}) ; get the queue name if available -exten => _*0[01]!,n,GotoIf($[${ISNULL(${thisQueue})} & ${EXISTS(${xtn})}]?invalid_queue,1) ; if 'thisQueue' is blank and the - ; the agent dialed a queue exten, - ; we will tell them it's invalid - -The following line will determine if we're trying to pause or unpause. This is -done by taking the value dialed (e.g. *00100) and chopping off the first 2 -digits which leaves us with 0100, and then the :1 will return the next digit, -which in this case is '0' that we're using to signify that the queue member -wants to be paused (in queue 100). - -So we're doing the following with our EXTEN variable. - - ${EXTEN:2:1} -offset ^ ^ length - - -Which causes the following. - - *00100 - ^^ offset these characters - - *00100 - ^ then return a digit length of one, which is digit 0 - - -exten => _*0[01]!,n,GotoIf($[${EXTEN:2:1} = 0]?pause,1:unpause,1) ; determine if they wanted to pause - ; or to unpause. - - -The following two extensions, pause & unpause, are used for pausing and -unpausing our extension from the queue(s). We use the PauseQueueMember() and -UnpauseQueueMember() dialplan applications which accept the queue name -(optional) and the queue member name. If the queue name is not provided, then it -is assumed we want to pause or unpause from all logged in queues. - -; Unpause ourselves from one or more queues -exten => unpause,1,NoOp() -exten => unpause,n,UnpauseQueueMember(${thisQueue},SIP/${CHANNEL(peername)}) ; if 'thisQueue' is populated we'll pause in - ; that queue, otherwise, we'll unpause in - ; in all queues - - -Once we've unpaused ourselves, we use GoSub() to perform some common dialplan -logic that is used for pausing and unpausing. We pass three arguments to the -subroutine: - - * variable name that contains the result of our operation - * the value we're expecting to get back if successful - * the filename to play - -exten => unpause,n,GoSub(changePauseStatus,start,1(UPQMSTATUS,UNPAUSED,available)) ; use the changePauseStatus subroutine and - ; pass the values for: variable to check, - ; value to check for, and file to play -exten => unpause,n,Hangup() - - -And the same method is done for pausing. - -; Pause ourselves in one or more queues -exten => pause,1,NoOp() -exten => pause,n,PauseQueueMember(${thisQueue},SIP/${CHANNEL(peername)}) -exten => pause,n,GoSub(changePauseStatus,start,1(PQMSTATUS,PAUSED,unavailable)) -exten => pause,n,Hangup() - - -Lets explore what happens in the subroutine we're using for pausing and -unpausing. - - -; ### Subroutine we use to check pausing and unpausing status ### -[changePauseStatus] -; ARG1: variable name to check, such as PQMSTATUS and UPQMSTATUS (PauseQueueMemberStatus / UnpauseQueueMemberStatus) -; ARG2: value to check for, such as PAUSED or UNPAUSED -; ARG3: file to play back if our variable value matched the value to check for -; -exten => start,1,NoOp() -exten => start,n,Playback(silence/1) ; answer line with silence - -The following line is probably the most complex. We're using the IF() function -inside the Playback() application which determines which file to playback -to the user. - -Those three values we passed in from the pause and unpause extensions could have -been something like: - - * ARG1 -- PQMSTATUS - * ARG2 -- PAUSED - * ARG3 -- unavailable - -So when expanded, we'd end up with the following inside the IF() function. - - $["${PQMSTATUS}" = "PAUSED"]?unavailable:not-yet-connected - -${PQMSTATUS} would then be expanded further to contain the status of our -PauseQueueMember() dialplan application, which could either be PAUSED or -NOTFOUND. So if ${PQMSTATUS} returned PAUSED, then it would match what we're -looking to match on, and we'd then return 'unavailable' to Playback() that would -tell the user they are now unavailable. - -Otherwise, we'd get back a message saying "not yet connected" to indicate they -are likely not logged into the queue they are attempting to change status in. - - -; Please note that ${ARG1} is wrapped in ${ } in order to expand the value of ${ARG1} into -; the variable we want to retrieve the value from, i.e. ${${ARG1}} turns into ${PQMSTATUS} -exten => start,n,Playback(${IF($["${${ARG1}}" = "${ARG2}"]?${ARG3}:not-yet-connected)}) ; check if value of variable - ; matches the value we're looking - ; for and playback the file we want - ; to play if it does - -If ${xtn} is null, then we just go to the end of the subroutine, but if it isn't -then we will play back "in the queue" followed by the queue extension number -indicating which queue they were (un)paused from. - -exten => start,n,GotoIf($[${ISNULL(${xtn})}]?end) ; if ${xtn} is null, then just Return() -exten => start,n,Playback(in-the-queue) ; if not null, then playback "in the queue" -exten => start,n,SayNumber(${xtn}) ; and the queue number that we (un)paused from -exten => start,n(end),Return() ; return from were we came - --------------- -| Conclusion | --------------- - -You should now have a simple system that permits you to login and out of queues -you create in queues.conf, and to allow queue members to pause themselves within -one or more queues. There are a lot of dialplan concepts utilized in this -article, so you are encouraged to seek out additional documentation if any of -these concepts are a bit fuzzy for you. - -A good start is the doc/ subdirectory of the Asterisk sources, or the various -configuration samples files located in the configs/ subdirectory of your -Asterisk source code. diff --git a/doc/callfiles.txt b/doc/callfiles.txt deleted file mode 100644 index 3fe6cb09e..000000000 --- a/doc/callfiles.txt +++ /dev/null @@ -1,139 +0,0 @@ -Asterisk call files -=================== - -Asterisk has the ability to initiate a call from outside of the normal -methods such as the dialplan, manager interface, or spooling interface. - -Using the call file method, you must give Asterisk the following information: - -* How to perform the call, similar to the Dial() application -* What to do when the call is answered - -With call files you submit this information simply by creating a file with -the required syntax and placing it in the outgoing spooling directory, located -by default in /var/spool/asterisk/outgoing/ (configurable in asterisk.conf). - -The pbx_spool module aggressively examines the directory contents every second, -creating a new call for every call file it finds. Do NOT write or create -the call file directly in the outgoing directory, but always create the file -in another directory of the same filesystem and then move the file to the -/var/spool/asterisk/outgoing directory, or Asterisk may read just a partial -file. - - -The call file syntax -==================== - -The call file consists of : pairs; one per line. - -Comments are indicated by a '#' character that begins a line, or follows a space -or tab character. To be consistent with the configuration files in Asterisk, -comments can also be indicated by a semicolon. However, the multiline comments -(;-- --;) used in Asterisk configuration files are not supported. Semicolons can -be escaped by a backslash. - - -The following keys-value pairs are used to specify how setup a call: - -Channel: the channel to use for the new call, in the form - technology/resource as in the Dial application. This - value is required. - -Callerid: the caller id to use. - -WaitTime: how many seconds to wait for an answer before the call - fails (ring cycle). Default 45 seconds. - -Maxretries: number of retries before failing, not including the - initial attempt. Default = 0 e.g. don't retry if fails. - -RetryTime: how many seconds to wait before retry. The default is - 300 (5 minutes). - -Account: the account code for the call. This value will be - assigned to CDR(accountcode) - - - -When the call answers there are two choices: -* Execute a single application, or -* Execute the dialplan at the specified context/extension/priority. - - -To execute an application: --------------------------- - -Application: the application to execute - -Data: the application arguments - - -To start executing applications in the dialplan: ------------------------------------------------- - -Context: the context in the dialplan - -Extension: the extension in the specified context - -Priority: the priority of the specified extension - (numeric or label) - - - -Setvar: you may also assign values to variables that will be - available to the channel, as if you had performed a - Set(var=value) in the dialplan. More than one Setvar: - maybe specified. - - -The processing of the call file ends when the call is answered and terminated; when -the call was not answered in the initial attempt and subsequent retries; or if -the call file can't be successfully read and parsed. - -To specify what to do with the call file at the end of processing: - -Archive: if "no" the call file is deleted. If set to "yes" the - call file is moved to the "outgoing_done" subdirectory - of the Asterisk spool directory. The default is to - delete the call file. - - -If the call file is archived, Asterisk will append to the call file: - -Status: can be "Expired", "Completed" or "Failed" - - - -Other lines generated by Asterisk: - -Asterisk keep track of how many retries the call has already attempted, -appending to the call file the following key-pairs in the form: - -StartRetry: (