aboutsummaryrefslogtreecommitdiffstats
path: root/trunk/include/asterisk
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/include/asterisk')
-rw-r--r--trunk/include/asterisk/_private.h53
-rw-r--r--trunk/include/asterisk/abstract_jb.h220
-rw-r--r--trunk/include/asterisk/acl.h84
-rw-r--r--trunk/include/asterisk/adsi.h353
-rw-r--r--trunk/include/asterisk/ael_structs.h123
-rw-r--r--trunk/include/asterisk/aes.h67
-rw-r--r--trunk/include/asterisk/aes_internal.h170
-rw-r--r--trunk/include/asterisk/agi.h66
-rw-r--r--trunk/include/asterisk/alaw.h86
-rw-r--r--trunk/include/asterisk/app.h463
-rw-r--r--trunk/include/asterisk/ast_expr.h40
-rw-r--r--trunk/include/asterisk/astdb.h58
-rw-r--r--trunk/include/asterisk/astmm.h82
-rw-r--r--trunk/include/asterisk/astobj.h819
-rw-r--r--trunk/include/asterisk/astobj2.h568
-rw-r--r--trunk/include/asterisk/astosp.h31
-rw-r--r--trunk/include/asterisk/audiohook.h210
-rw-r--r--trunk/include/asterisk/autoconfig.h.in1205
-rw-r--r--trunk/include/asterisk/callerid.h345
-rw-r--r--trunk/include/asterisk/causes.h149
-rw-r--r--trunk/include/asterisk/cdr.h337
-rw-r--r--trunk/include/asterisk/channel.h1577
-rw-r--r--trunk/include/asterisk/chanvars.h42
-rw-r--r--trunk/include/asterisk/cli.h285
-rw-r--r--trunk/include/asterisk/compat.h184
-rw-r--r--trunk/include/asterisk/compiler.h56
-rw-r--r--trunk/include/asterisk/config.h406
-rw-r--r--trunk/include/asterisk/crypto.h126
-rw-r--r--trunk/include/asterisk/devicestate.h203
-rw-r--r--trunk/include/asterisk/dial.h168
-rw-r--r--trunk/include/asterisk/dlfcn-compat.h88
-rw-r--r--trunk/include/asterisk/dns.h39
-rw-r--r--trunk/include/asterisk/dnsmgr.h62
-rw-r--r--trunk/include/asterisk/doxyref.h563
-rw-r--r--trunk/include/asterisk/dsp.h111
-rw-r--r--trunk/include/asterisk/dundi.h231
-rw-r--r--trunk/include/asterisk/endian.h69
-rw-r--r--trunk/include/asterisk/enum.h90
-rw-r--r--trunk/include/asterisk/event.h482
-rw-r--r--trunk/include/asterisk/event_defs.h143
-rw-r--r--trunk/include/asterisk/extconf.h248
-rw-r--r--trunk/include/asterisk/features.h112
-rw-r--r--trunk/include/asterisk/file.h322
-rw-r--r--trunk/include/asterisk/frame.h603
-rw-r--r--trunk/include/asterisk/fskmodem.h81
-rw-r--r--trunk/include/asterisk/global_datastores.h36
-rw-r--r--trunk/include/asterisk/hashtab.h324
-rw-r--r--trunk/include/asterisk/http.h93
-rw-r--r--trunk/include/asterisk/image.h90
-rw-r--r--trunk/include/asterisk/indications.h89
-rw-r--r--trunk/include/asterisk/inline_api.h66
-rw-r--r--trunk/include/asterisk/io.h150
-rw-r--r--trunk/include/asterisk/jabber.h201
-rw-r--r--trunk/include/asterisk/jingle.h61
l---------trunk/include/asterisk/libresample.h1
-rw-r--r--trunk/include/asterisk/linkedlists.h775
-rw-r--r--trunk/include/asterisk/localtime.h48
-rw-r--r--trunk/include/asterisk/lock.h1205
-rw-r--r--trunk/include/asterisk/logger.h178
-rw-r--r--trunk/include/asterisk/manager.h211
-rw-r--r--trunk/include/asterisk/md5.h38
-rw-r--r--trunk/include/asterisk/mod_format.h144
-rw-r--r--trunk/include/asterisk/module.h421
-rw-r--r--trunk/include/asterisk/monitor.h71
-rw-r--r--trunk/include/asterisk/musiconhold.h59
-rw-r--r--trunk/include/asterisk/netsock.h70
-rw-r--r--trunk/include/asterisk/network.h98
-rw-r--r--trunk/include/asterisk/options.h137
-rw-r--r--trunk/include/asterisk/paths.h39
-rw-r--r--trunk/include/asterisk/pbx.h978
-rw-r--r--trunk/include/asterisk/plc.h153
-rw-r--r--trunk/include/asterisk/poll-compat.h111
-rw-r--r--trunk/include/asterisk/privacy.h46
-rw-r--r--trunk/include/asterisk/pval.h273
-rw-r--r--trunk/include/asterisk/res_odbc.h122
-rw-r--r--trunk/include/asterisk/rtp.h293
-rw-r--r--trunk/include/asterisk/say.h170
-rw-r--r--trunk/include/asterisk/sched.h176
-rw-r--r--trunk/include/asterisk/sha1.h73
-rw-r--r--trunk/include/asterisk/slinfactory.h65
-rw-r--r--trunk/include/asterisk/smdi.h127
-rw-r--r--trunk/include/asterisk/speech.h156
-rw-r--r--trunk/include/asterisk/srv.h45
-rw-r--r--trunk/include/asterisk/stringfields.h307
-rw-r--r--trunk/include/asterisk/strings.h691
-rw-r--r--trunk/include/asterisk/tcptls.h166
-rw-r--r--trunk/include/asterisk/tdd.h82
-rw-r--r--trunk/include/asterisk/term.h85
-rw-r--r--trunk/include/asterisk/threadstorage.h212
-rw-r--r--trunk/include/asterisk/time.h178
-rw-r--r--trunk/include/asterisk/transcap.h46
-rw-r--r--trunk/include/asterisk/translate.h273
-rw-r--r--trunk/include/asterisk/udptl.h127
-rw-r--r--trunk/include/asterisk/ulaw.h87
-rw-r--r--trunk/include/asterisk/unaligned.h102
-rw-r--r--trunk/include/asterisk/utils.h657
-rw-r--r--trunk/include/asterisk/version.h44
-rw-r--r--trunk/include/asterisk/zapata.h48
98 files changed, 22318 insertions, 0 deletions
diff --git a/trunk/include/asterisk/_private.h b/trunk/include/asterisk/_private.h
new file mode 100644
index 000000000..06163cd53
--- /dev/null
+++ b/trunk/include/asterisk/_private.h
@@ -0,0 +1,53 @@
+/*
+ * Prototypes for public functions only of internal interest,
+ * normally not used by modules.
+ * What goes here are typically *_init() routines.
+ */
+
+/*! \file
+ *
+ * \brief
+ * Prototypes for public functions only of internal interest,
+ *
+ */
+
+
+#ifndef _ASTERISK__PRIVATE_H
+#define _ASTERISK__PRIVATE_H
+
+int load_modules(unsigned int); /*!< Provided by loader.c */
+int load_pbx(void); /*!< Provided by pbx.c */
+int init_logger(void); /*!< Provided by logger.c */
+void close_logger(void); /*!< Provided by logger.c */
+int init_framer(void); /*!< Provided by frame.c */
+int ast_term_init(void); /*!< Provided by term.c */
+int astdb_init(void); /*!< Provided by db.c */
+void ast_channels_init(void); /*!< Provided by channel.c */
+void ast_builtins_init(void); /*!< Provided by cli.c */
+int dnsmgr_init(void); /*!< Provided by dnsmgr.c */
+void dnsmgr_start_refresh(void); /*!< Provided by dnsmgr.c */
+int dnsmgr_reload(void); /*!< Provided by dnsmgr.c */
+void threadstorage_init(void); /*!< Provided by threadstorage.c */
+void ast_event_init(void); /*!< Provided by event.c */
+int ast_device_state_engine_init(void); /*!< Provided by devicestate.c */
+int astobj2_init(void); /*!< Provided by astobj2.c */
+int ast_file_init(void); /*!< Provided by file.c */
+
+/*!
+ * \brief Reload asterisk modules.
+ * \param name the name of the module to reload
+ *
+ * This function reloads the specified module, or if no modules are specified,
+ * it will reload all loaded modules.
+ *
+ * \note Modules are reloaded using their reload() functions, not unloading
+ * them and loading them again.
+ *
+ * \return 0 if the specified module was not found.
+ * \retval 1 if the module was found but cannot be reloaded.
+ * \retval -1 if a reload operation is already in progress.
+ * \retval 2 if the specfied module was found and reloaded.
+ */
+int ast_module_reload(const char *name);
+
+#endif /* _ASTERISK__PRIVATE_H */
diff --git a/trunk/include/asterisk/abstract_jb.h b/trunk/include/asterisk/abstract_jb.h
new file mode 100644
index 000000000..4a41c8c2c
--- /dev/null
+++ b/trunk/include/asterisk/abstract_jb.h
@@ -0,0 +1,220 @@
+/*
+ * abstract_jb: common implementation-independent jitterbuffer stuff
+ *
+ * Copyright (C) 2005, Attractel OOD
+ *
+ * Contributors:
+ * Slav Klenov <slav@securax.org>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ *
+ * A license has been granted to Digium (via disclaimer) for the use of
+ * this code.
+ */
+
+/*! \file
+ *
+ * \brief Common implementation-independent jitterbuffer stuff.
+ *
+ * \author Slav Klenov <slav@securax.org>
+ */
+
+#ifndef _ABSTRACT_JB_H_
+#define _ABSTRACT_JB_H_
+
+#include <sys/time.h>
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+struct ast_frame;
+
+/* Configuration flags */
+enum {
+ AST_JB_ENABLED = (1 << 0),
+ AST_JB_FORCED = (1 << 1),
+ AST_JB_LOG = (1 << 2)
+};
+
+#define AST_JB_IMPL_NAME_SIZE 12
+
+/*!
+ * \brief General jitterbuffer configuration.
+ */
+struct ast_jb_conf
+{
+ /*! \brief Combination of the AST_JB_ENABLED, AST_JB_FORCED and AST_JB_LOG flags. */
+ unsigned int flags;
+ /*! \brief Max size of the jitterbuffer implementation. */
+ long max_size;
+ /*! \brief Resynchronization threshold of the jitterbuffer implementation. */
+ long resync_threshold;
+ /*! \brief Name of the jitterbuffer implementation to be used. */
+ char impl[AST_JB_IMPL_NAME_SIZE];
+};
+
+
+/* Jitterbuffer configuration property names */
+#define AST_JB_CONF_PREFIX "jb"
+#define AST_JB_CONF_ENABLE "enable"
+#define AST_JB_CONF_FORCE "force"
+#define AST_JB_CONF_MAX_SIZE "maxsize"
+#define AST_JB_CONF_RESYNCH_THRESHOLD "resyncthreshold"
+#define AST_JB_CONF_IMPL "impl"
+#define AST_JB_CONF_LOG "log"
+
+
+struct ast_jb_impl;
+
+
+/*!
+ * \brief General jitterbuffer state.
+ */
+struct ast_jb
+{
+ /*! \brief Jitterbuffer configuration. */
+ struct ast_jb_conf conf;
+ /*! \brief Jitterbuffer implementation to be used. */
+ struct ast_jb_impl *impl;
+ /*! \brief Jitterbuffer object, passed to the implementation. */
+ void *jbobj;
+ /*! \brief The time the jitterbuffer was created. */
+ struct timeval timebase;
+ /*! \brief The time the next frame should be played. */
+ long next;
+ /*! \brief Voice format of the last frame in. */
+ int last_format;
+ /*! \brief File for frame timestamp tracing. */
+ FILE *logfile;
+ /*! \brief Jitterbuffer internal state flags. */
+ unsigned int flags;
+};
+
+
+/*!
+ * \brief Checks the need of a jb use in a generic bridge.
+ * \param c0 first bridged channel.
+ * \param c1 second bridged channel.
+ *
+ * Called from ast_generic_bridge() when two channels are entering in a bridge.
+ * The function checks the need of a jitterbuffer, depending on both channel's
+ * configuration and technology properties. As a result, this function sets
+ * appropriate internal jb flags to the channels, determining further behaviour
+ * of the bridged jitterbuffers.
+ *
+ * \retval zero if there are no jitter buffers in use
+ * \retval non-zero if there are
+ */
+int ast_jb_do_usecheck(struct ast_channel *c0, struct ast_channel *c1);
+
+
+/*!
+ * \brief Calculates the time, left to the closest delivery moment in a bridge.
+ * \param c0 first bridged channel.
+ * \param c1 second bridged channel.
+ * \param time_left bridge time limit, or -1 if not set.
+ *
+ * Called from ast_generic_bridge() to determine the maximum time to wait for
+ * activity in ast_waitfor_n() call. If neihter of the channels is using jb,
+ * this function returns the time limit passed.
+ *
+ * \return maximum time to wait.
+ */
+int ast_jb_get_when_to_wakeup(struct ast_channel *c0, struct ast_channel *c1, int time_left);
+
+
+/*!
+ * \brief Puts a frame into a channel jitterbuffer.
+ * \param chan channel.
+ * \param f frame.
+ *
+ * Called from ast_generic_bridge() to put a frame into a channel's jitterbuffer.
+ * The function will successfuly enqueue a frame if and only if:
+ * 1. the channel is using a jitterbuffer (as determined by ast_jb_do_usecheck()),
+ * 2. the frame's type is AST_FRAME_VOICE,
+ * 3. the frame has timing info set and has length >= 2 ms,
+ * 4. there is no some internal error happened (like failed memory allocation).
+ * Frames, successfuly queued, should be delivered by the channel's jitterbuffer,
+ * when their delivery time has came.
+ * Frames, not successfuly queued, should be delivered immediately.
+ * Dropped by the jb implementation frames are considered successfuly enqueued as
+ * far as they should not be delivered at all.
+ *
+ * \retval 0 if the frame was queued
+ * \retval -1 if not
+ */
+int ast_jb_put(struct ast_channel *chan, struct ast_frame *f);
+
+
+/*!
+ * \brief Deliver the queued frames that should be delivered now for both channels.
+ * \param c0 first bridged channel.
+ * \param c1 second bridged channel.
+ *
+ * Called from ast_generic_bridge() to deliver any frames, that should be delivered
+ * for the moment of invocation. Does nothing if neihter of the channels is using jb
+ * or has any frames currently queued in. The function delivers frames usig ast_write()
+ * each of the channels.
+ */
+void ast_jb_get_and_deliver(struct ast_channel *c0, struct ast_channel *c1);
+
+
+/*!
+ * \brief Destroys jitterbuffer on a channel.
+ * \param chan channel.
+ *
+ * Called from ast_channel_free() when a channel is destroyed.
+ */
+void ast_jb_destroy(struct ast_channel *chan);
+
+
+/*!
+ * \brief Sets jitterbuffer configuration property.
+ * \param conf configuration to store the property in.
+ * \param varname property name.
+ * \param value property value.
+ *
+ * Called from a channel driver to build a jitterbuffer configuration tipically when
+ * reading a configuration file. It is not neccessary for a channel driver to know
+ * each of the jb configuration property names. The jitterbuffer itself knows them.
+ * The channel driver can pass each config var it reads through this function. It will
+ * return 0 if the variable was consumed from the jb conf.
+ *
+ * \return zero if the property was set to the configuration, -1 if not.
+ */
+int ast_jb_read_conf(struct ast_jb_conf *conf, const char *varname, const char *value);
+
+
+/*!
+ * \brief Configures a jitterbuffer on a channel.
+ * \param chan channel to configure.
+ * \param conf configuration to apply.
+ *
+ * Called from a channel driver when a channel is created and its jitterbuffer needs
+ * to be configured.
+ */
+void ast_jb_configure(struct ast_channel *chan, const struct ast_jb_conf *conf);
+
+
+/*!
+ * \brief Copies a channel's jitterbuffer configuration.
+ * \param chan channel.
+ * \param conf destination.
+ */
+void ast_jb_get_config(const struct ast_channel *chan, struct ast_jb_conf *conf);
+
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _ABSTRACT_JB_H_ */
diff --git a/trunk/include/asterisk/acl.h b/trunk/include/asterisk/acl.h
new file mode 100644
index 000000000..79b787d70
--- /dev/null
+++ b/trunk/include/asterisk/acl.h
@@ -0,0 +1,84 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2006, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief Access Control of various sorts
+ */
+
+#ifndef _ASTERISK_ACL_H
+#define _ASTERISK_ACL_H
+
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+#include "asterisk/network.h"
+#include "asterisk/io.h"
+
+#define AST_SENSE_DENY 0
+#define AST_SENSE_ALLOW 1
+
+/* Host based access control */
+
+/*! \brief internal representation of acl entries
+ * In principle user applications would have no need for this,
+ * but there is sometimes a need to extract individual items,
+ * e.g. to print them, and rather than defining iterators to
+ * navigate the list, and an externally visible 'struct ast_ha_entry',
+ * at least in the short term it is more convenient to make the whole
+ * thing public and let users play with them.
+ */
+struct ast_ha {
+ /* Host access rule */
+ struct in_addr netaddr;
+ struct in_addr netmask;
+ int sense;
+ struct ast_ha *next;
+};
+
+/*! \brief Free host access list */
+void ast_free_ha(struct ast_ha *ha);
+
+/*! \brief Append ACL entry to host access list. */
+struct ast_ha *ast_append_ha(const char *sense, const char *stuff, struct ast_ha *path, int *error);
+
+/*! \brief Check IP address with host access list */
+int ast_apply_ha(struct ast_ha *ha, struct sockaddr_in *sin);
+
+/*! \brief Copy host access list */
+struct ast_ha *ast_duplicate_ha_list(struct ast_ha *original);
+
+int ast_get_ip(struct sockaddr_in *sin, const char *value);
+
+int ast_get_ip_or_srv(struct sockaddr_in *sin, const char *value, const char *service);
+
+int ast_ouraddrfor(struct in_addr *them, struct in_addr *us);
+
+int ast_find_ourip(struct in_addr *ourip, struct sockaddr_in bindaddr);
+
+int ast_str2cos(const char *value, unsigned int *cos);
+
+int ast_str2tos(const char *value, unsigned int *tos);
+const char *ast_tos2str(unsigned int tos);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _ASTERISK_ACL_H */
diff --git a/trunk/include/asterisk/adsi.h b/trunk/include/asterisk/adsi.h
new file mode 100644
index 000000000..3c31574a5
--- /dev/null
+++ b/trunk/include/asterisk/adsi.h
@@ -0,0 +1,353 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2005, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief ADSI Support (built upon Caller*ID)
+ */
+
+#ifndef _ASTERISK_ADSI_H
+#define _ASTERISK_ADSI_H
+
+#include "asterisk/callerid.h"
+/*! \name ADSI parameters */
+/*@{ */
+
+/* ADSI Message types */
+#define ADSI_MSG_DISPLAY 132
+#define ADSI_MSG_DOWNLOAD 133
+
+/* ADSI Parameters (display) */
+#define ADSI_LOAD_SOFTKEY 128
+#define ADSI_INIT_SOFTKEY_LINE 129
+#define ADSI_LOAD_VIRTUAL_DISP 130
+#define ADSI_LINE_CONTROL 131
+#define ADSI_INFORMATION 132
+#define ADSI_DISC_SESSION 133
+#define ADSI_SWITCH_TO_DATA 134
+#define ADSI_SWITCH_TO_VOICE 135
+#define ADSI_CLEAR_SOFTKEY 136
+#define ADSI_INPUT_CONTROL 137
+#define ADSI_INPUT_FORMAT 138
+#define ADSI_SWITCH_TO_PERIPH 139
+#define ADSI_MOVE_DATA 140
+#define ADSI_LOAD_DEFAULT 141
+#define ADSI_CONNECT_SESSION 142
+#define ADSI_CLEAR_TYPE_AHEAD 143
+#define ADSI_DISPLAY_CALL_BUF 144
+#define ADSI_CLEAR_CALL_BUF 145
+#define ADSI_SWITCH_TO_ALT 146
+#define ADSI_SWITCH_TO_GRAPHICS 147
+#define ADSI_CLEAR_SCREEN 148
+#define ADSI_QUERY_CONFIG 149
+#define ADSI_QUERY_CPEID 150
+#define ADSI_SWITCH_TO_APP 151
+
+/* Feature download messages */
+#define ADSI_LOAD_SOFTKEY_TABLE 128 /* Conveniently identical to the soft version */
+#define ADSI_LOAD_PREDEF_DISP 129 /* Load predefined display */
+#define ADSI_LOAD_SCRIPT 130
+#define ADSI_DOWNLOAD_CONNECT 131
+#define ADSI_DOWNLOAD_DISC 132
+
+/* Special return string codes */
+#define ADSI_ENCODED_DTMF 0x80 /* Transmit following chars with encoded dtmf */
+#define ADSI_ON_HOOK 0x81 /* Open switch-hook */
+#define ADSI_OFF_HOOK 0x82 /* Close switch-hook */
+#define ADSI_FLASH 0x83 /* Flash switch-hook */
+#define ADSI_DIAL_TONE_DETECT 0x84 /* Wait for dialtone */
+#define ADSI_LINE_NUMBER 0x85 /* Send current line number using DTMF/encoded DTMF */
+#define ADSI_BLANK 0x86 /* Blank (does nothing) */
+#define ADSI_SEND_CHARS 0x87 /* Send collected digits/characters */
+#define ADSI_CLEAR_CHARS 0x88 /* Clear characters/digits collected */
+#define ADSI_BACKSPACE 0x89 /* Erase last collected digit */
+#define ADSI_TAB_COLUMN 0x8A /* Display specified display column of current line */
+#define ADSI_GOTO_LINE 0x8B /* Go to given page and line number */
+#define ADSI_GOTO_LINE_REL 0x8C /* Go to given line (relative to current) */
+#define ADSI_PAGE_UP 0x8D /* Go up one page */
+#define ADSI_PAGE_DOWN 0x8E /* Go down one page */
+#define ADSI_EXTENDED_DTMF 0x8F /* Send DTMF tones for 250ms instead of 60 ms */
+#define ADSI_DELAY 0x90 /* Delay for given # (times 10) of ms */
+#define ADSI_DIAL_PULSE_ONE 0x91 /* Send a dial pulse "1" */
+#define ADSI_SWITCH_TO_DATA2 0x92 /* Switch CPE to data mode */
+#define ADSI_SWITCH_TO_VOICE2 0x93 /* Switch CPE to voice mode */
+#define ADSI_DISP_CALL_BUF 0x94 /* Display specified call buffer */
+#define ADSI_CLEAR_CALL_B 0x95 /* Clear specified call buffer */
+
+#ifdef __ADSI_CPE
+/* These messages are reserved for the ADSI CPE only */
+#define ADSI_DISPLAY_CONTROL 0x98 /* Store predefined display identified next / Display status display page */
+#define ADSI_DISPLAY_SOFT_KEYS 0x99 /* Display the script soft keys identified next */
+#define ADSI_CHANGE_STATE 0x9A /* Change state of service script */
+#define ADSI_START_CLEAR_TIMER 0x9B /* Start / Clear timer */
+#define ADSI_SET_SCRIPT_FLAG 0x9C /* Set / clear a script flag */
+#define ADSI_JUMP_TO_SUBSCRIPT 0x9D /* Jump to specified subscript */
+#define ADSI_EVENT_22_TRIGGER 0x9E /* Trigger an occurance of event 22 */
+#define ADSI_EVENT_23_TRIGGER 0x9f /* Trigger an occurance of event 23 */
+#define ADSI_EXIT 0xA0 /* Exit the service script interpreter */
+#endif
+
+/* Display pages */
+#define ADSI_INFO_PAGE 0x0
+#define ADSI_COMM_PAGE 0x1
+
+#define ADSI_KEY_APPS 16 /* 16 to 33 reserved for applications */
+
+/* Justification */
+#define ADSI_JUST_LEFT 0x2
+#define ADSI_JUST_RIGHT 0x1
+#define ADSI_JUST_CENT 0x0 /* Center */
+#define ADSI_JUST_IND 0x3 /* Indent */
+
+#define ADSI_KEY_SKT 0x80 /* Load from SKT */
+#define ADSI_KEY_HILITE 0x40 /* Highlight key */
+
+#define ADSI_DIR_FROM_LEFT (0)
+#define ADSI_DIR_FROM_RIGHT (1)
+
+/*@} */
+
+/*! Perform Asterisk ADSI initialization (for channel drivers that want
+ * to support ADSI when the handset is first lifted)
+ * \param chan Channel to initialize for ADSI (if supported)
+ *
+ * \retval 0 on success (or adsi unavailable.
+ * \retval -1 on hangup.
+ */
+extern int (*ast_adsi_channel_init)(struct ast_channel *chan);
+
+extern int (*ast_adsi_begin_download)(struct ast_channel *chan, char *service, unsigned char *fdn, unsigned char *sec, int version);
+
+extern int (*ast_adsi_end_download)(struct ast_channel *chan);
+
+/*! Restore ADSI initialization (for applications that play with ADSI
+ * and want to restore it to normal. If you touch "INFO" then you
+ * have to use the ast_adsi_channel_init again instead.
+ * \param chan Channel to restore
+ *
+ * \retval 0 on success (or adsi unavailable)
+ * \retval -1 on hangup
+ */
+extern int (*ast_adsi_channel_restore)(struct ast_channel *chan);
+
+/*!
+ * \brief Display some stuff on the screen
+ * \param chan Channel to display on
+ * \param lines NULL-terminated list of things to print (no more than 4 recommended)
+ * \param align list of alignments to use (ADSI_JUST_LEFT, ADSI_JUST_RIGHT, ADSI_JUST_CEN, etc..)
+ * \param voice whether to jump into voice mode when finished
+ *
+ * \retval 0 on success (or adsi unavailable)
+ * \retval -1 on hangup
+ */
+extern int (*ast_adsi_print)(struct ast_channel *chan, char **lines, int *align, int voice);
+
+/*!
+ * \brief Check if scripts for a given app are already loaded.
+ * Version may be -1, if any version is okay, or 0-255 for a specific version.
+ * \param chan Channel to test for loaded app
+ * \param app Four character app name (must be unique to your application)
+ * \param ver optional version number
+ * \param data Non-zero if you want to be put in data mode
+ *
+ * \retval 0 if scripts is not loaded or not an ADSI CPE
+ * \retval -1 on hangup
+ * \retval 1 if script already loaded.
+ */
+extern int (*ast_adsi_load_session)(struct ast_channel *chan, unsigned char *app, int ver, int data);
+extern int (*ast_adsi_unload_session)(struct ast_channel *chan);
+
+/* ADSI Layer 2 transmission functions */
+extern int (*ast_adsi_transmit_messages)(struct ast_channel *chan, unsigned char **msg, int *msglen, int *msgtype);
+extern int (*ast_adsi_transmit_message)(struct ast_channel *chan, unsigned char *msg, int msglen, int msgtype);
+extern int (*ast_adsi_transmit_message_full)(struct ast_channel *chan, unsigned char *msg, int msglen, int msgtype, int dowait);
+/*! Read some encoded DTMF data.
+ * Returns number of bytes received
+ */
+extern int (*ast_adsi_read_encoded_dtmf)(struct ast_channel *chan, unsigned char *buf, int maxlen);
+
+/* ADSI Layer 3 creation functions */
+
+/*!
+ * \brief Connects an ADSI Display Session
+ * \param buf Character buffer to create parameter in (must have at least 256 free)
+ * \param fdn Optional 4 byte Feature Download Number (for loading soft keys)
+ * \param ver Optional version number (0-255, or -1 to omit)
+ *
+ * \retval number of bytes added to buffer
+ * \retval -1 on error.
+ */
+
+extern int (*ast_adsi_connect_session)(unsigned char *buf, unsigned char *fdn, int ver);
+
+/*! Build Query CPE ID of equipment.
+ * Returns number of bytes added to message
+ */
+extern int (*ast_adsi_query_cpeid)(unsigned char *buf);
+extern int (*ast_adsi_query_cpeinfo)(unsigned char *buf);
+
+/*! Get CPE ID from an attached ADSI compatible CPE.
+ * Returns 1 on success, storing 4 bytes of CPE ID at buf
+ * or -1 on hangup, or 0 if there was no hangup but it failed to find the
+ * device ID. Returns to voice mode if "voice" is non-zero.
+ */
+extern int (*ast_adsi_get_cpeid)(struct ast_channel *chan, unsigned char *cpeid, int voice);
+
+extern int (*ast_adsi_get_cpeinfo)(struct ast_channel *chan, int *width, int *height, int *buttons, int voice);
+
+/*!
+ * \brief Begin an ADSI script download
+ * \param buf Character buffer to create parameter in (must have at least 256 free)
+ * \param service a 1-18 byte name of the feature
+ * \param fdn 4 byte Feature Download Number (for loading soft keys)
+ * \param sec 4 byte vendor security code
+ * \param ver version number (0-255, or -1 to omit)
+ *
+ * \retval number of bytes added to buffer
+ * \retval -1 on error.
+ */
+
+extern int (*ast_adsi_download_connect)(unsigned char *buf, char *service, unsigned char *fdn, unsigned char *sec, int ver);
+
+/*!
+ * \brief Disconnects a running session.
+ * \param buf Character buffer to create parameter in (must have at least 256 free)
+ *
+ * \retval number of bytes added to buffer
+ * \retval -1 on error.
+ */
+extern int (*ast_adsi_disconnect_session)(unsigned char *buf);
+
+/*!
+ * \brief Disconnects (and hopefully saves) a downloaded script
+ * \param buf Character buffer to create parameter in (must have at least 256 free)
+ *
+ * \retval number of bytes added to buffer
+ * \retval -1 on error.
+ */
+extern int (*ast_adsi_download_disconnect)(unsigned char *buf);
+
+/*!
+ * \brief Puts CPE in data mode.
+ * \param buf Character buffer to create parameter in (must have at least 256 free)
+ *
+ * \retval number of bytes added to buffer
+ * \retval -1 on error.
+ */
+extern int (*ast_adsi_data_mode)(unsigned char *buf);
+extern int (*ast_adsi_clear_soft_keys)(unsigned char *buf);
+extern int (*ast_adsi_clear_screen)(unsigned char *buf);
+
+/*!
+ * \brief Puts CPE in voice mode.
+ * \param buf Character buffer to create parameter in (must have at least 256 free)
+ * \param when (a time in seconds) to make the switch
+ *
+ * \retval number of bytes added to buffer
+ * \retval -1 on error.
+ */
+extern int (*ast_adsi_voice_mode)(unsigned char *buf, int when);
+
+/*!
+ * \brief Returns non-zero if Channel does or might support ADSI
+ * \param chan Channel to check
+ */
+extern int (*ast_adsi_available)(struct ast_channel *chan);
+
+/*!
+ * \brief Loads a line of info into the display.
+ * \param buf Character buffer to create parameter in (must have at least 256 free)
+ * \param page Page to load (ADSI_COMM_PAGE or ADSI_INFO_PAGE)
+ * \param line Line number to load (1-4 for Comm page, 1-33 for info page)
+ * \param just Line justification (ADSI_JUST_LEFT, ADSI_JUST_RIGHT, ADSI_JUST_CENT, ADSI_JUST_IND)
+ * \param wrap Wrap (1 = yes, 0 = no)
+ * \param col1 Text to place in first column
+ * \param col2 Text to place in second column
+ *
+ * \retval number of bytes added to buffer
+ * \retval -1 on error.
+ */
+
+extern int (*ast_adsi_display)(unsigned char *buf, int page, int line, int just, int wrap, char *col1, char *col2);
+
+/*!
+ * \brief Sets the current line and page.
+ * \param buf Character buffer to create parameter in (must have at least 256 free)
+ * \param page Which page (ADSI_COMM_PAGE or ADSI_INFO_PAGE)
+ * \param line Line number (1-33 for info page, 1-4 for comm page)
+ *
+ * \retval number of bytes added to buffer
+ * \retval -1 on error.
+ */
+
+extern int (*ast_adsi_set_line)(unsigned char *buf, int page, int line);
+
+/*!
+ * \brief Creates "load soft key" parameters
+ * \param buf Character buffer to create parameter in (must have at least 256 free)
+ * \param key Key code from 2 to 33, for which key we are loading
+ * \param llabel Long label for key (1-18 bytes)
+ * \param slabel Short label for key (1-7 bytes)
+ * \param ret Optional return sequence (NULL for none)
+ * \param data whether to put CPE in data mode before sending digits
+ *
+ * \retval number of bytes added to buffer
+ * \retval -1 on error.
+ */
+extern int (*ast_adsi_load_soft_key)(unsigned char *buf, int key, const char *llabel, const char *slabel, char *ret, int data);
+
+/*!
+ * \brief Set which soft keys should be displayed
+ * \param buf Character buffer to create parameter in (must have at least 256 free)
+ * \param keys Array of 8 unsigned chars with the key numbers, may be OR'd with ADSI_KEY_HILITE
+ * But remember, the last two keys aren't real keys, they're for scrolling
+ *
+ * \retval number of bytes added to buffer
+ * \retval -1 on error.
+ */
+extern int (*ast_adsi_set_keys)(unsigned char *buf, unsigned char *keys);
+
+/*!
+ * \brief Set input information
+ * \param buf Character buffer to create parameter in (must have at least 256 free)
+ * \param page Which page to input on (ADSI_COMM_PAGE or ADSI_INFO_PAGE)
+ * \param line Line number to input on
+ * \param display Set to zero to obscure input, or 1 to leave visible
+ * \param format Format number to use (0-7)
+ * \param just Justification (left, right center, indent)
+ *
+ * \retval number of bytes added to buffer
+ * \retval -1 on error.
+ */
+extern int (*ast_adsi_input_control)(unsigned char *buf, int page, int line, int display, int format, int just);
+
+/*!
+ * \brief Set input format
+ * \param buf Character buffer to create parameter in (must have at least 256 free)
+ * \param num Which format we are setting
+ * \param dir Which direction (ADSI_DIR_FROM_LEFT or ADSI_DIR_FROM_RIGHT)
+ * \param wrap Set to 1 to permit line wrap, or 0 if not
+ * \param format1 Format for column 1
+ * \param format2 Format for column 2
+ *
+ * \retval number of bytes added to buffer
+ * \retval -1 on error.
+ */
+extern int (*ast_adsi_input_format)(unsigned char *buf, int num, int dir, int wrap, char *format1, char *format2);
+
+#endif /* _ASTERISK_ADSI_H */
+
diff --git a/trunk/include/asterisk/ael_structs.h b/trunk/include/asterisk/ael_structs.h
new file mode 100644
index 000000000..0a58ed378
--- /dev/null
+++ b/trunk/include/asterisk/ael_structs.h
@@ -0,0 +1,123 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2007, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief Structures for AEL - the Asterisk extension language
+ *
+ * \ref pbx_ael.c
+ * \todo document this file (ael.h)
+ */
+
+#ifndef _ASTERISK_AEL_STRUCTS_H
+#define _ASTERISK_AEL_STRUCTS_H
+
+/*
+ * We include asterisk/paths.h here because it is a convenient place
+ * that doesn't require us to rebuild ael files from .fl/.y
+ */
+#include "asterisk/paths.h"
+
+#include "pval.h"
+
+#if !defined(SOLARIS) && !defined(__CYGWIN__)
+/* #include <err.h> */
+#else
+#define quad_t int64_t
+#endif
+
+#if defined(LONG_LONG_MIN) && !defined(QUAD_MIN)
+#define QUAD_MIN LONG_LONG_MIN
+#endif
+#if defined(LONG_LONG_MAX) && !defined(QUAD_MAX)
+#define QUAD_MAX LONG_LONG_MAX
+#endif
+
+# if ! defined(QUAD_MIN)
+# define QUAD_MIN (-0x7fffffffffffffffLL-1)
+# endif
+# if ! defined(QUAD_MAX)
+# define QUAD_MAX (0x7fffffffffffffffLL)
+# endif
+
+
+#if 0
+#endif
+void ael2_semantic_check(pval *item, int *errs, int *warns, int *notes);
+pval *npval(pvaltype type, int first_line, int last_line, int first_column, int last_column);
+pval *linku1(pval *head, pval *tail);
+void ael2_print(char *fname, pval *tree);
+struct pval *ael2_parse(char *fname, int *errs); /* in ael.flex */
+void destroy_pval(pval *item);
+
+extern char *prev_word; /* in ael.flex */
+
+#ifndef YY_TYPEDEF_YY_SCANNER_T
+#define YY_TYPEDEF_YY_SCANNER_T
+typedef void* yyscan_t;
+#endif
+
+/* for passing info into and out of yyparse */
+struct parse_io
+{
+ struct pval *pval; /* yyparse will set this to point to the parse tree */
+ yyscan_t scanner; /* yylex needs a scanner. Set it up, and pass it in */
+ int syntax_error_count; /* the count of syntax errors encountered */
+};
+
+/* for CODE GENERATION */
+
+typedef enum { AEL_APPCALL, AEL_CONTROL1, AEL_FOR_CONTROL, AEL_IF_CONTROL, AEL_IFTIME_CONTROL, AEL_RAND_CONTROL, AEL_LABEL, AEL_RETURN } ael_priority_type;
+
+
+struct ael_priority
+{
+ int priority_num;
+ ael_priority_type type;
+
+ char *app;
+ char *appargs;
+
+ struct pval *origin;
+ struct ael_extension *exten;
+
+ struct ael_priority *goto_true;
+ struct ael_priority *goto_false;
+ struct ael_priority *next;
+};
+
+struct ael_extension
+{
+ char *name;
+ char *cidmatch;
+ char *hints;
+ int regexten;
+ int is_switch;
+
+ struct ast_context *context;
+
+ struct ael_priority *plist;
+ struct ael_priority *plist_last;
+ struct ael_extension *next_exten;
+
+ struct ael_priority *loop_break; /*!< set by latest loop for breaks */
+ struct ael_priority *loop_continue; /*!< set by lastest loop for continuing */
+ struct ael_priority *return_target;
+ int return_needed;
+};
+
+#endif /* _ASTERISK_AEL_STRUCTS_H */
diff --git a/trunk/include/asterisk/aes.h b/trunk/include/asterisk/aes.h
new file mode 100644
index 000000000..25e76153f
--- /dev/null
+++ b/trunk/include/asterisk/aes.h
@@ -0,0 +1,67 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 20075, Digium, Inc.
+ *
+ * Kevin P. Fleming <kpfleming@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * Wrappers for AES encryption/decryption
+ *
+ * \author Kevin P. Fleming <kpfleming@digium.com>
+ *
+ * These wrappers provided a generic interface to either the
+ * AES methods provided by OpenSSL's crypto library, or the
+ * AES implementation included with Asterisk.
+ */
+
+#ifndef _ASTERISK_AES_H
+#define _ASTERISK_AES_H
+
+#ifdef HAVE_CRYPTO
+
+/* Use the OpenSSL crypto library */
+#include "openssl/aes.h"
+
+typedef AES_KEY ast_aes_encrypt_key;
+typedef AES_KEY ast_aes_decrypt_key;
+
+#define ast_aes_encrypt_key(key, context) AES_set_encrypt_key(key, 1024, context)
+
+#define ast_aes_decrypt_key(key, context) AES_set_decrypt_key(key, 1024, context)
+
+#define ast_aes_encrypt(in, out, context) AES_encrypt(in, out, context)
+
+#define ast_aes_decrypt(in, out, context) AES_decrypt(in, out, context)
+
+#else /* !HAVE_CRYPTO */
+
+/* Use the included AES implementation */
+
+#include "aes_internal.h"
+
+typedef aes_encrypt_ctx ast_aes_encrypt_key;
+typedef aes_decrypt_ctx ast_aes_decrypt_key;
+
+#define ast_aes_encrypt_key(key, context) aes_encrypt_key128(key, context)
+
+#define ast_aes_decrypt_key(key, context) aes_decrypt_key128(key, context)
+
+#define ast_aes_encrypt(in, out, context) aes_encrypt(in, out, context)
+
+#define ast_aes_decrypt(in, out, context) aes_decrypt(in, out, context)
+
+#endif /* !HAVE_CRYPTO */
+
+#endif /* _ASTERISK_AES_H */
diff --git a/trunk/include/asterisk/aes_internal.h b/trunk/include/asterisk/aes_internal.h
new file mode 100644
index 000000000..18c27a6d4
--- /dev/null
+++ b/trunk/include/asterisk/aes_internal.h
@@ -0,0 +1,170 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ */
+
+/*
+ ---------------------------------------------------------------------------
+ Copyright (c) 2003, Dr Brian Gladman <brg@gladman.me.uk>, Worcester, UK.
+ All rights reserved.
+
+ LICENSE TERMS
+
+ The free distribution and use of this software in both source and binary
+ form is allowed (with or without changes) provided that:
+
+ 1. distributions of this source code include the above copyright
+ notice, this list of conditions and the following disclaimer;
+
+ 2. distributions in binary form include the above copyright
+ notice, this list of conditions and the following disclaimer
+ in the documentation and/or other associated materials;
+
+ 3. the copyright holder's name is not used to endorse products
+ built using this software without specific written permission.
+
+ ALTERNATIVELY, provided that this notice is retained in full, this product
+ may be distributed under the terms of the GNU General Public License (GPL),
+ in which case the provisions of the GPL apply INSTEAD OF those given above.
+
+ DISCLAIMER
+
+ This software is provided 'as is' with no explicit or implied warranties
+ in respect of its properties, including, but not limited to, correctness
+ and/or fitness for purpose.
+ ---------------------------------------------------------------------------
+ Issue Date: 26/08/2003
+*/
+/*!\file
+
+ \brief This file contains the definitions required to use AES in C. See aesopt.h
+ for optimisation details.
+*/
+
+#ifndef _AES_INTERNAL_H
+#define _AES_INTERNAL_H
+
+/* This include is used to find 8 & 32 bit unsigned integer types */
+#include "limits.h"
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+#define AES_128 /* define if AES with 128 bit keys is needed */
+#undef AES_192 /* define if AES with 192 bit keys is needed */
+#undef AES_256 /* define if AES with 256 bit keys is needed */
+#undef AES_VAR /* define if a variable key size is needed */
+
+/* The following must also be set in assembler files if being used */
+
+#define AES_ENCRYPT /* if support for encryption is needed */
+#define AES_DECRYPT /* if support for decryption is needed */
+#define AES_ERR_CHK /* for parameter checks & error return codes */
+
+#if UCHAR_MAX == 0xff /* an unsigned 8 bit type */
+ typedef unsigned char aes_08t;
+#else
+#error Please define aes_08t as an 8-bit unsigned integer type in aes.h
+#endif
+
+#if UINT_MAX == 0xffffffff /* an unsigned 32 bit type */
+ typedef unsigned int aes_32t;
+#elif ULONG_MAX == 0xffffffff
+ typedef unsigned long aes_32t;
+#else
+#error Please define aes_32t as a 32-bit unsigned integer type in aes.h
+#endif
+
+#define AES_BLOCK_SIZE 16 /* the AES block size in bytes */
+#define N_COLS 4 /* the number of columns in the state */
+
+/* a maximum of 60 32-bit words are needed for the key schedule but */
+/* 64 are claimed to allow space at the top for a CBC xor buffer. */
+/* If this is not needed, this value can be reduced to 60. A value */
+/* of 64 may also help in maintaining alignment in some situations */
+#define KS_LENGTH 64
+
+#ifdef AES_ERR_CHK
+#define aes_ret int
+#define aes_good 0
+#define aes_error -1
+#else
+#define aes_ret void
+#endif
+
+#ifndef AES_DLL /* implement normal/DLL functions */
+#define aes_rval aes_ret
+#else
+#define aes_rval aes_ret __declspec(dllexport) _stdcall
+#endif
+
+/* This routine must be called before first use if non-static */
+/* tables are being used */
+
+void gen_tabs(void);
+
+/* The key length (klen) is input in bytes when it is in the range */
+/* 16 <= klen <= 32 or in bits when in the range 128 <= klen <= 256 */
+
+#ifdef AES_ENCRYPT
+
+typedef struct
+{ aes_32t ks[KS_LENGTH];
+} aes_encrypt_ctx;
+
+#if defined(AES_128) || defined(AES_VAR)
+aes_rval aes_encrypt_key128(const void *in_key, aes_encrypt_ctx cx[1]);
+#endif
+
+#if defined(AES_192) || defined(AES_VAR)
+aes_rval aes_encrypt_key192(const void *in_key, aes_encrypt_ctx cx[1]);
+#endif
+
+#if defined(AES_256) || defined(AES_VAR)
+aes_rval aes_encrypt_key256(const void *in_key, aes_encrypt_ctx cx[1]);
+#endif
+
+#if defined(AES_VAR)
+aes_rval aes_encrypt_key(const void *in_key, int key_len, aes_encrypt_ctx cx[1]);
+#endif
+
+aes_rval aes_encrypt(const void *in_blk, void *out_blk, const aes_encrypt_ctx cx[1]);
+#endif
+
+#ifdef AES_DECRYPT
+
+typedef struct
+{ aes_32t ks[KS_LENGTH];
+} aes_decrypt_ctx;
+
+#if defined(AES_128) || defined(AES_VAR)
+aes_rval aes_decrypt_key128(const void *in_key, aes_decrypt_ctx cx[1]);
+#endif
+
+#if defined(AES_192) || defined(AES_VAR)
+aes_rval aes_decrypt_key192(const void *in_key, aes_decrypt_ctx cx[1]);
+#endif
+
+#if defined(AES_256) || defined(AES_VAR)
+aes_rval aes_decrypt_key256(const void *in_key, aes_decrypt_ctx cx[1]);
+#endif
+
+#if defined(AES_VAR)
+aes_rval aes_decrypt_key(const void *in_key, int key_len, aes_decrypt_ctx cx[1]);
+#endif
+
+aes_rval aes_decrypt(const void *in_blk, void *out_blk, const aes_decrypt_ctx cx[1]);
+#endif
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/trunk/include/asterisk/agi.h b/trunk/include/asterisk/agi.h
new file mode 100644
index 000000000..5085f05df
--- /dev/null
+++ b/trunk/include/asterisk/agi.h
@@ -0,0 +1,66 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2005, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief AGI Extension interfaces - Asterisk Gateway Interface
+ */
+
+#ifndef _ASTERISK_AGI_H
+#define _ASTERISK_AGI_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+typedef struct agi_state {
+ int fd; /*!< FD for general output */
+ int audio; /*!< FD for audio output */
+ int ctrl; /*!< FD for input control */
+ unsigned int fast:1; /*!< flag for fast agi or not */
+ struct ast_speech *speech; /*!< Speech structure for speech recognition */
+} AGI;
+
+typedef struct agi_command {
+ /* Null terminated list of the words of the command */
+ char *cmda[AST_MAX_CMD_LEN];
+ /* Handler for the command (channel, AGI state, # of arguments, argument list).
+ Returns RESULT_SHOWUSAGE for improper arguments */
+ int (*handler)(struct ast_channel *chan, AGI *agi, int argc, char *argv[]);
+ /* Summary of the command (< 60 characters) */
+ char *summary;
+ /* Detailed usage information */
+ char *usage;
+ /* Does this application run dead */
+ int dead;
+ /* Pointer to module that registered the agi command */
+ struct ast_module *mod;
+ /* Linked list pointer */
+ AST_LIST_ENTRY(agi_command) list;
+} agi_command;
+
+int ast_agi_fdprintf(struct ast_channel *chan, int fd, char *fmt, ...);
+int ast_agi_register(struct ast_module *mod, agi_command *cmd);
+int ast_agi_unregister(struct ast_module *mod, agi_command *cmd);
+void ast_agi_register_multiple(struct ast_module *mod, agi_command *cmd, int len);
+void ast_agi_unregister_multiple(struct ast_module *mod, agi_command *cmd, int len);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _ASTERISK_AGI_H */
diff --git a/trunk/include/asterisk/alaw.h b/trunk/include/asterisk/alaw.h
new file mode 100644
index 000000000..0ef42becc
--- /dev/null
+++ b/trunk/include/asterisk/alaw.h
@@ -0,0 +1,86 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2005, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief A-Law to Signed linear conversion
+ */
+
+#ifndef _ASTERISK_ALAW_H
+#define _ASTERISK_ALAW_H
+
+
+/*! \brief
+ * To init the alaw to slinear conversion stuff, this needs to be run.
+ */
+void ast_alaw_init(void);
+
+#define AST_ALAW_BIT_LOSS 4
+#define AST_ALAW_STEP (1 << AST_ALAW_BIT_LOSS)
+#define AST_ALAW_TAB_SIZE (32768 / AST_ALAW_STEP + 1)
+#define AST_ALAW_SIGN_BIT 0x80
+#define AST_ALAW_AMI_MASK 0x55
+
+
+/*! \brief converts signed linear to alaw */
+#ifndef G711_NEW_ALGORITHM
+extern unsigned char __ast_lin2a[8192];
+#else
+extern unsigned char __ast_lin2a[AST_ALAW_TAB_SIZE];
+#endif
+
+/*! help */
+extern short __ast_alaw[256];
+
+#ifndef G711_NEW_ALGORITHM
+#define AST_LIN2A(a) (__ast_lin2a[((unsigned short)(a)) >> 3])
+#else
+#define AST_LIN2A_LOOKUP(mag) \
+ __ast_lin2a[(mag) >> AST_ALAW_BIT_LOSS]
+
+/*! \brief Convert signed linear sample to sign-magnitude pair for a-Law */
+static inline void ast_alaw_get_sign_mag(short sample, unsigned *sign, unsigned *mag)
+{
+ /* It may look illogical to retrive the sign this way in both cases,
+ * but this helps gcc eliminate the branch below and produces
+ * faster code */
+ *sign = ((unsigned short)sample >> 8) & AST_ALAW_SIGN_BIT;
+#if defined(G711_REDUCED_BRANCHING)
+ {
+ unsigned dual_mag = (-sample << 16) | (unsigned short)sample;
+ *mag = (dual_mag >> (*sign >> 3)) & 0xffffU;
+ }
+#else
+ if (sample < 0)
+ *mag = -sample;
+ else
+ *mag = sample;
+#endif /* G711_REDUCED_BRANCHING */
+ *sign ^= AST_ALAW_SIGN_BIT;
+}
+
+static inline unsigned char AST_LIN2A(short sample)
+{
+ unsigned mag, sign;
+ ast_alaw_get_sign_mag(sample, &sign, &mag);
+ return (sign | AST_LIN2A_LOOKUP(mag)) ^ AST_ALAW_AMI_MASK;
+}
+#endif
+
+#define AST_ALAW(a) (__ast_alaw[(int)(a)])
+
+#endif /* _ASTERISK_ALAW_H */
diff --git a/trunk/include/asterisk/app.h b/trunk/include/asterisk/app.h
new file mode 100644
index 000000000..5be236608
--- /dev/null
+++ b/trunk/include/asterisk/app.h
@@ -0,0 +1,463 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2005, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief Application convenience functions, designed to give consistent
+ * look and feel to Asterisk apps.
+ */
+
+#ifndef _ASTERISK_APP_H
+#define _ASTERISK_APP_H
+
+struct ast_flags64;
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/* IVR stuff */
+
+/*! \brief Callback function for IVR
+ \return returns 0 on completion, -1 on hangup or digit if interrupted
+ */
+typedef int (*ast_ivr_callback)(struct ast_channel *chan, char *option, void *cbdata);
+
+typedef enum {
+ AST_ACTION_UPONE, /*!< adata is unused */
+ AST_ACTION_EXIT, /*!< adata is the return value for ast_ivr_menu_run if channel was not hungup */
+ AST_ACTION_CALLBACK, /*!< adata is an ast_ivr_callback */
+ AST_ACTION_PLAYBACK, /*!< adata is file to play */
+ AST_ACTION_BACKGROUND, /*!< adata is file to play */
+ AST_ACTION_PLAYLIST, /*!< adata is list of files, separated by ; to play */
+ AST_ACTION_MENU, /*!< adata is a pointer to an ast_ivr_menu */
+ AST_ACTION_REPEAT, /*!< adata is max # of repeats, cast to a pointer */
+ AST_ACTION_RESTART, /*!< adata is like repeat, but resets repeats to 0 */
+ AST_ACTION_TRANSFER, /*!< adata is a string with exten\verbatim[@context]\endverbatim */
+ AST_ACTION_WAITOPTION, /*!< adata is a timeout, or 0 for defaults */
+ AST_ACTION_NOOP, /*!< adata is unused */
+ AST_ACTION_BACKLIST, /*!< adata is list of files separated by ; allows interruption */
+} ast_ivr_action;
+
+/*!
+ Special "options" are:
+ \arg "s" - "start here (one time greeting)"
+ \arg "g" - "greeting/instructions"
+ \arg "t" - "timeout"
+ \arg "h" - "hangup"
+ \arg "i" - "invalid selection"
+
+*/
+struct ast_ivr_option {
+ char *option;
+ ast_ivr_action action;
+ void *adata;
+};
+
+struct ast_ivr_menu {
+ char *title; /*!< Title of menu */
+ unsigned int flags; /*!< Flags */
+ struct ast_ivr_option *options; /*!< All options */
+};
+
+#define AST_IVR_FLAG_AUTORESTART (1 << 0)
+
+#define AST_IVR_DECLARE_MENU(holder, title, flags, foo...) \
+ static struct ast_ivr_option __options_##holder[] = foo;\
+ static struct ast_ivr_menu holder = { title, flags, __options_##holder }
+
+
+/*! \brief Runs an IVR menu
+ \return returns 0 on successful completion, -1 on hangup, or -2 on user error in menu */
+int ast_ivr_menu_run(struct ast_channel *c, struct ast_ivr_menu *menu, void *cbdata);
+
+/*! \brief Plays a stream and gets DTMF data from a channel
+ * \param c Which channel one is interacting with
+ * \param prompt File to pass to ast_streamfile (the one that you wish to play).
+ * It is also valid for this to be multiple files concatenated by "&".
+ * For example, "file1&file2&file3".
+ * \param s The location where the DTMF data will be stored
+ * \param maxlen Max Length of the data
+ * \param timeout Timeout length waiting for data(in milliseconds). Set to 0 for standard timeout(six seconds), or -1 for no time out.
+ *
+ * This function was designed for application programmers for situations where they need
+ * to play a message and then get some DTMF data in response to the message. If a digit
+ * is pressed during playback, it will immediately break out of the message and continue
+ * execution of your code.
+ */
+int ast_app_getdata(struct ast_channel *c, const char *prompt, char *s, int maxlen, int timeout);
+
+/*! \brief Full version with audiofd and controlfd. NOTE: returns '2' on ctrlfd available, not '1' like other full functions */
+int ast_app_getdata_full(struct ast_channel *c, char *prompt, char *s, int maxlen, int timeout, int audiofd, int ctrlfd);
+
+void ast_install_vm_functions(int (*has_voicemail_func)(const char *mailbox, const char *folder),
+ int (*inboxcount_func)(const char *mailbox, int *newmsgs, int *oldmsgs),
+ int (*messagecount_func)(const char *context, const char *mailbox, const char *folder));
+
+void ast_uninstall_vm_functions(void);
+
+/*! \brief Determine if a given mailbox has any voicemail */
+int ast_app_has_voicemail(const char *mailbox, const char *folder);
+
+/*! \brief Determine number of new/old messages in a mailbox */
+int ast_app_inboxcount(const char *mailbox, int *newmsgs, int *oldmsgs);
+
+/*! \brief Determine number of messages in a given mailbox and folder */
+int ast_app_messagecount(const char *context, const char *mailbox, const char *folder);
+
+/*! \brief Safely spawn an external program while closing file descriptors
+ \note This replaces the \b system call in all Asterisk modules
+*/
+int ast_safe_system(const char *s);
+
+/*!
+ * \brief Replace the SIGCHLD handler
+ *
+ * Normally, Asterisk has a SIGCHLD handler that is cleaning up all zombie
+ * processes from forking elsewhere in Asterisk. However, if you want to
+ * wait*() on the process to retrieve information about it's exit status,
+ * then this signal handler needs to be temporarily replaced.
+ *
+ * Code that executes this function *must* call ast_unreplace_sigchld()
+ * after it is finished doing the wait*().
+ */
+void ast_replace_sigchld(void);
+
+/*!
+ * \brief Restore the SIGCHLD handler
+ *
+ * This function is called after a call to ast_replace_sigchld. It restores
+ * the SIGCHLD handler that cleans up any zombie processes.
+ */
+void ast_unreplace_sigchld(void);
+
+/*!
+ \brief Send DTMF to a channel
+
+ \param chan The channel that will receive the DTMF frames
+ \param peer (optional) Peer channel that will be autoserviced while the
+ primary channel is receiving DTMF
+ \param digits This is a string of characters representing the DTMF digits
+ to be sent to the channel. Valid characters are
+ "0123456789*#abcdABCD". Note: You can pass arguments 'f' or
+ 'F', if you want to Flash the channel (if supported by the
+ channel), or 'w' to add a 500 millisecond pause to the DTMF
+ sequence.
+ \param between This is the number of milliseconds to wait in between each
+ DTMF digit. If zero milliseconds is specified, then the
+ default value of 100 will be used.
+ \param duration This is the duration that each DTMF digit should have.
+*/
+int ast_dtmf_stream(struct ast_channel *chan, struct ast_channel *peer, const char *digits, int between, unsigned int duration);
+
+/*! \brief Stream a filename (or file descriptor) as a generator. */
+int ast_linear_stream(struct ast_channel *chan, const char *filename, int fd, int allowoverride);
+
+/*!
+ * \brief Stream a file with fast forward, pause, reverse, restart.
+ * \param chan
+ * \param file filename
+ * \param fwd, rev, stop, pause, restart, skipms, offsetms
+ *
+ * Before calling this function, set this to be the number
+ * of ms to start from the beginning of the file. When the function
+ * returns, it will be the number of ms from the beginning where the
+ * playback stopped. Pass NULL if you don't care.
+ */
+int ast_control_streamfile(struct ast_channel *chan, const char *file, const char *fwd, const char *rev, const char *stop, const char *pause, const char *restart, int skipms, long *offsetms);
+
+/*! \brief Play a stream and wait for a digit, returning the digit that was pressed */
+int ast_play_and_wait(struct ast_channel *chan, const char *fn);
+
+int ast_play_and_record_full(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime_sec, const char *fmt, int *duration, int silencethreshold, int maxsilence_ms, const char *path, const char *acceptdtmf, const char *canceldtmf);
+
+/*! \brief Record a file for a max amount of time (in seconds), in a given list of formats separated by '|', outputting the duration of the recording, and with a maximum
+ \n
+ permitted silence time in milliseconds of 'maxsilence' under 'silencethreshold' or use '-1' for either or both parameters for defaults.
+ calls ast_unlock_path() on 'path' if passed */
+int ast_play_and_record(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime_sec, const char *fmt, int *duration, int silencethreshold, int maxsilence_ms, const char *path);
+
+/*! \brief Record a message and prepend the message to the given record file after
+ playing the optional playfile (or a beep), storing the duration in
+ 'duration' and with a maximum permitted silence time in milliseconds of 'maxsilence' under
+ 'silencethreshold' or use '-1' for either or both parameters for defaults. */
+int ast_play_and_prepend(struct ast_channel *chan, char *playfile, char *recordfile, int maxtime_sec, char *fmt, int *duration, int beep, int silencethreshold, int maxsilence_ms);
+
+enum AST_LOCK_RESULT {
+ AST_LOCK_SUCCESS = 0,
+ AST_LOCK_TIMEOUT = -1,
+ AST_LOCK_PATH_NOT_FOUND = -2,
+ AST_LOCK_FAILURE = -3,
+};
+
+/*! \brief Type of locking to use in ast_lock_path / ast_unlock_path */
+enum AST_LOCK_TYPE {
+ AST_LOCK_TYPE_LOCKFILE = 0,
+ AST_LOCK_TYPE_FLOCK = 1,
+};
+
+/*!
+ * \brief Set the type of locks used by ast_lock_path()
+ * \param type the locking type to use
+ */
+void ast_set_lock_type(enum AST_LOCK_TYPE type);
+
+/*!
+ * \brief Lock a filesystem path.
+ * \param path the path to be locked
+ * \return one of \ref AST_LOCK_RESULT values
+ */
+enum AST_LOCK_RESULT ast_lock_path(const char *path);
+
+/*! \brief Unlock a path */
+int ast_unlock_path(const char *path);
+
+/*! \brief Read a file into asterisk*/
+char *ast_read_textfile(const char *file);
+
+struct ast_group_info;
+
+/*! \brief Split a group string into group and category, returning a default category if none is provided. */
+int ast_app_group_split_group(const char *data, char *group, int group_max, char *category, int category_max);
+
+/*! \brief Set the group for a channel, splitting the provided data into group and category, if specified. */
+int ast_app_group_set_channel(struct ast_channel *chan, const char *data);
+
+/*! \brief Get the current channel count of the specified group and category. */
+int ast_app_group_get_count(const char *group, const char *category);
+
+/*! \brief Get the current channel count of all groups that match the specified pattern and category. */
+int ast_app_group_match_get_count(const char *groupmatch, const char *category);
+
+/*! \brief Discard all group counting for a channel */
+int ast_app_group_discard(struct ast_channel *chan);
+
+/*! \brief Update all group counting for a channel to a new one */
+int ast_app_group_update(struct ast_channel *oldchan, struct ast_channel *newchan);
+
+/*! \brief Write Lock the group count list */
+int ast_app_group_list_wrlock(void);
+
+/*! \brief Read Lock the group count list */
+int ast_app_group_list_rdlock(void);
+
+/*! \brief Get the head of the group count list */
+struct ast_group_info *ast_app_group_list_head(void);
+
+/*! \brief Unlock the group count list */
+int ast_app_group_list_unlock(void);
+
+/*!
+ \brief Define an application argument
+ \param name The name of the argument
+*/
+#define AST_APP_ARG(name) char *name
+
+/*!
+ \brief Declare a structure to hold the application's arguments.
+ \param name The name of the structure
+ \param arglist The list of arguments, defined using AST_APP_ARG
+
+ This macro defines a structure intended to be used in a call
+ to ast_app_separate_args(). The structure includes all the
+ arguments specified, plus an argv array that overlays them and an
+ argc argument counter. The arguments must be declared using AST_APP_ARG,
+ and they will all be character pointers (strings).
+
+ \note The structure is <b>not</b> initialized, as the call to
+ ast_app_separate_args() will perform that function before parsing
+ the arguments.
+ */
+#define AST_DECLARE_APP_ARGS(name, arglist) \
+ struct { \
+ unsigned int argc; \
+ char *argv[0]; \
+ arglist \
+ } name
+
+/*!
+ \brief Performs the 'standard' argument separation process for an application.
+ \param args An argument structure defined using AST_DECLARE_APP_ARGS
+ \param parse A modifiable buffer containing the input to be parsed
+
+ This function will separate the input string using the standard argument
+ separator character ',' and fill in the provided structure, including
+ the argc argument counter field.
+ */
+#define AST_STANDARD_APP_ARGS(args, parse) \
+ args.argc = ast_app_separate_args(parse, ',', args.argv, (sizeof(args) - sizeof(args.argc)) / sizeof(args.argv[0]))
+
+/*!
+ \brief Performs the 'nonstandard' argument separation process for an application.
+ \param args An argument structure defined using AST_DECLARE_APP_ARGS
+ \param parse A modifiable buffer containing the input to be parsed
+ \param sep A nonstandard separator character
+
+ This function will separate the input string using the nonstandard argument
+ separator character and fill in the provided structure, including
+ the argc argument counter field.
+ */
+#define AST_NONSTANDARD_APP_ARGS(args, parse, sep) \
+ args.argc = ast_app_separate_args(parse, sep, args.argv, (sizeof(args) - sizeof(args.argc)) / sizeof(args.argv[0]))
+
+/*!
+ \brief Separate a string into arguments in an array
+ \param buf The string to be parsed (this must be a writable copy, as it will be modified)
+ \param delim The character to be used to delimit arguments
+ \param array An array of 'char *' to be filled in with pointers to the found arguments
+ \param arraylen The number of elements in the array (i.e. the number of arguments you will accept)
+
+ Note: if there are more arguments in the string than the array will hold, the last element of
+ the array will contain the remaining arguments, not separated.
+
+ The array will be completely zeroed by this function before it populates any entries.
+
+ \return The number of arguments found, or zero if the function arguments are not valid.
+*/
+unsigned int ast_app_separate_args(char *buf, char delim, char **array, int arraylen);
+
+/*!
+ \brief A structure to hold the description of an application 'option'.
+
+ Application 'options' are single-character flags that can be supplied
+ to the application to affect its behavior; they can also optionally
+ accept arguments enclosed in parenthesis.
+
+ These structures are used by the ast_app_parse_options function, uses
+ this data to fill in a flags structure (to indicate which options were
+ supplied) and array of argument pointers (for those options that had
+ arguments supplied).
+ */
+struct ast_app_option {
+ /*! \brief The flag bit that represents this option. */
+ uint64_t flag;
+ /*! \brief The index of the entry in the arguments array
+ that should be used for this option's argument. */
+ unsigned int arg_index;
+};
+
+#define BEGIN_OPTIONS {
+#define END_OPTIONS }
+
+/*!
+ \brief Declares an array of options for an application.
+ \param holder The name of the array to be created
+ \param options The actual options to be placed into the array
+ \sa ast_app_parse_options
+
+ This macro declares a 'static const' array of \c struct \c ast_option
+ elements to hold the list of available options for an application.
+ Each option must be declared using either the AST_APP_OPTION()
+ or AST_APP_OPTION_ARG() macros.
+
+ Example usage:
+ \code
+ enum {
+ OPT_JUMP = (1 << 0),
+ OPT_BLAH = (1 << 1),
+ OPT_BLORT = (1 << 2),
+ } my_app_option_flags;
+
+ enum {
+ OPT_ARG_BLAH = 0,
+ OPT_ARG_BLORT,
+ !! this entry tells how many possible arguments there are,
+ and must be the last entry in the list
+ OPT_ARG_ARRAY_SIZE,
+ } my_app_option_args;
+
+ AST_APP_OPTIONS(my_app_options, {
+ AST_APP_OPTION('j', OPT_JUMP),
+ AST_APP_OPTION_ARG('b', OPT_BLAH, OPT_ARG_BLAH),
+ AST_APP_OPTION_BLORT('B', OPT_BLORT, OPT_ARG_BLORT),
+ });
+
+ static int my_app_exec(struct ast_channel *chan, void *data)
+ {
+ char *options;
+ struct ast_flags opts = { 0, };
+ char *opt_args[OPT_ARG_ARRAY_SIZE];
+
+ ... do any argument parsing here ...
+
+ if (ast_parseoptions(my_app_options, &opts, opt_args, options)) {
+ ast_module_user_remove(u);
+ return -1;
+ }
+ }
+ \endcode
+ */
+#define AST_APP_OPTIONS(holder, options...) \
+ static const struct ast_app_option holder[128] = options
+
+/*!
+ \brief Declares an application option that does not accept an argument.
+ \param option The single character representing the option
+ \param flagno The flag index to be set if this option is present
+ \sa AST_APP_OPTIONS, ast_app_parse_options
+ */
+#define AST_APP_OPTION(option, flagno) \
+ [option] = { .flag = flagno }
+
+/*!
+ \brief Declares an application option that accepts an argument.
+ \param option The single character representing the option
+ \param flagno The flag index to be set if this option is present
+ \param argno The index into the argument array where the argument should
+ be placed
+ \sa AST_APP_OPTIONS, ast_app_parse_options
+ */
+#define AST_APP_OPTION_ARG(option, flagno, argno) \
+ [option] = { .flag = flagno, .arg_index = argno + 1 }
+
+/*!
+ \brief Parses a string containing application options and sets flags/arguments.
+ \param options The array of possible options declared with AST_APP_OPTIONS
+ \param flags The flag structure to have option flags set
+ \param args The array of argument pointers to hold arguments found
+ \param optstr The string containing the options to be parsed
+ \return zero for success, non-zero if an error occurs
+ \sa AST_APP_OPTIONS
+ */
+int ast_app_parse_options(const struct ast_app_option *options, struct ast_flags *flags, char **args, char *optstr);
+
+ /*!
+ \brief Parses a string containing application options and sets flags/arguments.
+ \param options The array of possible options declared with AST_APP_OPTIONS
+ \param flags The 64-bit flag structure to have option flags set
+ \param args The array of argument pointers to hold arguments found
+ \param optstr The string containing the options to be parsed
+ \return zero for success, non-zero if an error occurs
+ \sa AST_APP_OPTIONS
+ */
+int ast_app_parse_options64(const struct ast_app_option *options, struct ast_flags64 *flags, char **args, char *optstr);
+
+/*! \brief Present a dialtone and collect a certain length extension.
+ \return Returns 1 on valid extension entered, -1 on hangup, or 0 on invalid extension.
+\note Note that if 'collect' holds digits already, new digits will be appended, so be sure it's initialized properly */
+int ast_app_dtget(struct ast_channel *chan, const char *context, char *collect, size_t size, int maxlen, int timeout);
+
+/*! \brief Allow to record message and have a review option */
+int ast_record_review(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, const char *path);
+
+/*! \brief Decode an encoded control or extended ASCII character */
+int ast_get_encoded_char(const char *stream, char *result, size_t *consumed);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _ASTERISK_APP_H */
diff --git a/trunk/include/asterisk/ast_expr.h b/trunk/include/asterisk/ast_expr.h
new file mode 100644
index 000000000..a89b7b9a1
--- /dev/null
+++ b/trunk/include/asterisk/ast_expr.h
@@ -0,0 +1,40 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2005, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ *
+ * ???????
+ * \todo Explain this file!
+ */
+
+
+#ifndef _ASTERISK_EXPR_H
+#define _ASTERISK_EXPR_H
+#ifndef STANDALONE
+#endif
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+int ast_expr(char *expr, char *buf, int length, struct ast_channel *chan);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _ASTERISK_EXPR_H */
diff --git a/trunk/include/asterisk/astdb.h b/trunk/include/asterisk/astdb.h
new file mode 100644
index 000000000..e19784bad
--- /dev/null
+++ b/trunk/include/asterisk/astdb.h
@@ -0,0 +1,58 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2005, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief Persistant data storage (akin to *doze registry)
+ */
+
+#ifndef _ASTERISK_ASTDB_H
+#define _ASTERISK_ASTDB_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+struct ast_db_entry {
+ struct ast_db_entry *next;
+ char *key;
+ char data[0];
+};
+
+/*! \brief Get key value specified by family/key */
+int ast_db_get(const char *family, const char *key, char *out, int outlen);
+
+/*! \brief Store value addressed by family/key*/
+int ast_db_put(const char *family, const char *key, const char *value);
+
+/*! \brief Delete entry in astdb */
+int ast_db_del(const char *family, const char *key);
+
+/*! \brief Delete a whole family (for some reason also called "tree" */
+int ast_db_deltree(const char *family, const char *keytree);
+
+/*! \brief Get a whole family */
+struct ast_db_entry *ast_db_gettree(const char *family, const char *keytree);
+
+/*! \brief Free in-memory data */
+void ast_db_freetree(struct ast_db_entry *entry);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _ASTERISK_ASTDB_H */
diff --git a/trunk/include/asterisk/astmm.h b/trunk/include/asterisk/astmm.h
new file mode 100644
index 000000000..4487c17aa
--- /dev/null
+++ b/trunk/include/asterisk/astmm.h
@@ -0,0 +1,82 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2006, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief Asterisk memory usage debugging
+ */
+
+#ifndef _ASTERISK_ASTMM_H
+#define _ASTERISK_ASTMM_H
+
+#define __AST_DEBUG_MALLOC
+
+#include "asterisk.h"
+
+/* Undefine any macros */
+#undef malloc
+#undef calloc
+#undef realloc
+#undef strdup
+#undef strndup
+#undef asprintf
+#undef vasprintf
+
+void *__ast_calloc(size_t nmemb, size_t size, const char *file, int lineno, const char *func);
+void *__ast_calloc_cache(size_t nmemb, size_t size, const char *file, int lineno, const char *func);
+void *__ast_malloc(size_t size, const char *file, int lineno, const char *func);
+void __ast_free(void *ptr, const char *file, int lineno, const char *func);
+void *__ast_realloc(void *ptr, size_t size, const char *file, int lineno, const char *func);
+char *__ast_strdup(const char *s, const char *file, int lineno, const char *func);
+char *__ast_strndup(const char *s, size_t n, const char *file, int lineno, const char *func);
+int __ast_asprintf(const char *file, int lineno, const char *func, char **strp, const char *format, ...);
+int __ast_vasprintf(char **strp, const char *format, va_list ap, const char *file, int lineno, const char *func);
+
+void __ast_mm_init(void);
+
+
+/* Provide our own definitions */
+#define calloc(a,b) \
+ __ast_calloc(a,b,__FILE__, __LINE__, __PRETTY_FUNCTION__)
+
+#define ast_calloc_cache(a,b) \
+ __ast_calloc_cache(a,b,__FILE__, __LINE__, __PRETTY_FUNCTION__)
+
+#define malloc(a) \
+ __ast_malloc(a,__FILE__, __LINE__, __PRETTY_FUNCTION__)
+
+#define free(a) \
+ __ast_free(a,__FILE__, __LINE__, __PRETTY_FUNCTION__)
+
+#define realloc(a,b) \
+ __ast_realloc(a,b,__FILE__, __LINE__, __PRETTY_FUNCTION__)
+
+#define strdup(a) \
+ __ast_strdup(a,__FILE__, __LINE__, __PRETTY_FUNCTION__)
+
+#define strndup(a,b) \
+ __ast_strndup(a,b,__FILE__, __LINE__, __PRETTY_FUNCTION__)
+
+#define asprintf(a, b, c...) \
+ __ast_asprintf(__FILE__, __LINE__, __PRETTY_FUNCTION__, a, b, c)
+
+#define vasprintf(a,b,c) \
+ __ast_vasprintf(a,b,c,__FILE__, __LINE__, __PRETTY_FUNCTION__)
+
+#else
+#error "NEVER INCLUDE astmm.h DIRECTLY!!"
+#endif /* _ASTERISK_ASTMM_H */
diff --git a/trunk/include/asterisk/astobj.h b/trunk/include/asterisk/astobj.h
new file mode 100644
index 000000000..cca463f42
--- /dev/null
+++ b/trunk/include/asterisk/astobj.h
@@ -0,0 +1,819 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2005, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*
+ * Object Model for Asterisk
+ */
+
+#ifndef _ASTERISK_ASTOBJ_H
+#define _ASTERISK_ASTOBJ_H
+
+#include "asterisk/lock.h"
+
+/*! \file
+ * \brief A set of macros implementing objects and containers.
+ * Macros are used for maximum performance, to support multiple inheritance,
+ * and to be easily integrated into existing structures without additional
+ * malloc calls, etc.
+ *
+ * These macros expect to operate on two different object types, ASTOBJs and
+ * ASTOBJ_CONTAINERs. These are not actual types, as any struct can be
+ * converted into an ASTOBJ compatible object or container using the supplied
+ * macros.
+ *
+ * <b>Sample Usage:</b>
+ * \code
+ * struct sample_object {
+ * ASTOBJ_COMPONENTS(struct sample_object);
+ * };
+ *
+ * struct sample_container {
+ * ASTOBJ_CONTAINER_COMPONENTS(struct sample_object);
+ * } super_container;
+ *
+ * void sample_object_destroy(struct sample_object *obj)
+ * {
+ * free(obj);
+ * }
+ *
+ * int init_stuff()
+ * {
+ * struct sample_object *obj1;
+ * struct sample_object *found_obj;
+ *
+ * obj1 = malloc(sizeof(struct sample_object));
+ *
+ * ASTOBJ_CONTAINER_INIT(&super_container);
+ *
+ * ASTOBJ_INIT(obj1);
+ * ASTOBJ_WRLOCK(obj1);
+ * ast_copy_string(obj1->name, "obj1", sizeof(obj1->name));
+ * ASTOBJ_UNLOCK(obj1);
+ *
+ * ASTOBJ_CONTAINER_LINK(&super_container, obj1);
+ *
+ * found_obj = ASTOBJ_CONTAINER_FIND(&super_container, "obj1");
+ *
+ * if(found_obj) {
+ * printf("Found object: %s", found_obj->name);
+ * ASTOBJ_UNREF(found_obj,sample_object_destroy);
+ * }
+ *
+ * ASTOBJ_CONTAINER_DESTROYALL(&super_container,sample_object_destroy);
+ * ASTOBJ_CONTAINER_DESTROY(&super_container);
+ *
+ * return 0;
+ * }
+ * \endcode
+ */
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+#define ASTOBJ_DEFAULT_NAMELEN 80
+#define ASTOBJ_DEFAULT_BUCKETS 256
+#define ASTOBJ_DEFAULT_HASH ast_strhash
+
+#define ASTOBJ_FLAG_MARKED (1 << 0) /* Object has been marked for future operation */
+
+/* C++ is simply a syntactic crutch for those who cannot think for themselves
+ in an object oriented way. */
+
+/*! \brief Lock an ASTOBJ for reading.
+ */
+#define ASTOBJ_RDLOCK(object) ast_mutex_lock(&(object)->_lock)
+
+/*! \brief Lock an ASTOBJ for writing.
+ */
+#define ASTOBJ_WRLOCK(object) ast_mutex_lock(&(object)->_lock)
+
+/*! \brief Unlock a locked object. */
+#define ASTOBJ_UNLOCK(object) ast_mutex_unlock(&(object)->_lock)
+
+#ifdef ASTOBJ_CONTAINER_HASHMODEL
+#define __ASTOBJ_HASH(type,hashes) \
+ type *next[hashes]
+#else
+#define __ASTOBJ_HASH(type,hashes) \
+ type *next[1]
+#endif
+
+/*! \brief Add ASTOBJ components to a struct (without locking support).
+ *
+ * \param type The datatype of the object.
+ * \param namelen The length to make the name char array.
+ * \param hashes The number of containers the object can be present in.
+ *
+ * This macro adds components to a struct to make it an ASTOBJ. This macro
+ * differs from ASTOBJ_COMPONENTS_FULL in that it does not create a mutex for
+ * locking.
+ *
+ * <b>Sample Usage:</b>
+ * \code
+ * struct sample_struct {
+ * ASTOBJ_COMPONENTS_NOLOCK_FULL(struct sample_struct,1,1);
+ * };
+ * \endcode
+ */
+#define ASTOBJ_COMPONENTS_NOLOCK_FULL(type,namelen,hashes) \
+ char name[namelen]; \
+ unsigned int refcount; \
+ unsigned int objflags; \
+ __ASTOBJ_HASH(type,hashes)
+
+/*! \brief Add ASTOBJ components to a struct (without locking support).
+ *
+ * \param type The datatype of the object.
+ *
+ * This macro works like #ASTOBJ_COMPONENTS_NOLOCK_FULL() except it only accepts a
+ * type and uses default values for namelen and hashes.
+ *
+ * <b>Sample Usage:</b>
+ * \code
+ * struct sample_struct_componets {
+ * ASTOBJ_COMPONENTS_NOLOCK(struct sample_struct);
+ * };
+ * \endcode
+ */
+#define ASTOBJ_COMPONENTS_NOLOCK(type) \
+ ASTOBJ_COMPONENTS_NOLOCK_FULL(type,ASTOBJ_DEFAULT_NAMELEN,1)
+
+/*! \brief Add ASTOBJ components to a struct (with locking support).
+ *
+ * \param type The datatype of the object.
+ *
+ * This macro works like #ASTOBJ_COMPONENTS_NOLOCK() except it includes locking
+ * support.
+ *
+ * <b>Sample Usage:</b>
+ * \code
+ * struct sample_struct {
+ * ASTOBJ_COMPONENTS(struct sample_struct);
+ * };
+ * \endcode
+ */
+#define ASTOBJ_COMPONENTS(type) \
+ ASTOBJ_COMPONENTS_NOLOCK(type); \
+ ast_mutex_t _lock;
+
+/*! \brief Add ASTOBJ components to a struct (with locking support).
+ *
+ * \param type The datatype of the object.
+ * \param namelen The length to make the name char array.
+ * \param hashes The number of containers the object can be present in.
+ *
+ * This macro adds components to a struct to make it an ASTOBJ and includes
+ * support for locking.
+ *
+ * <b>Sample Usage:</b>
+ * \code
+ * struct sample_struct {
+ * ASTOBJ_COMPONENTS_FULL(struct sample_struct,1,1);
+ * };
+ * \endcode
+ */
+#define ASTOBJ_COMPONENTS_FULL(type,namelen,hashes) \
+ ASTOBJ_COMPONENTS_NOLOCK_FULL(type,namelen,hashes); \
+ ast_mutex_t _lock;
+
+/*! \brief Increment an object reference count.
+ * \param object A pointer to the object to operate on.
+ * \return The object.
+ */
+#define ASTOBJ_REF(object) \
+ ({ \
+ ASTOBJ_WRLOCK(object); \
+ (object)->refcount++; \
+ ASTOBJ_UNLOCK(object); \
+ (object); \
+ })
+
+/*! \brief Decrement the reference count on an object.
+ *
+ * \param object A pointer the object to operate on.
+ * \param destructor The destructor to call if the object is no longer referenced. It will be passed the pointer as an argument.
+ *
+ * This macro unreferences an object and calls the specfied destructor if the
+ * object is no longer referenced. The destructor should free the object if it
+ * was dynamically allocated.
+ */
+#define ASTOBJ_UNREF(object,destructor) \
+ do { \
+ int newcount = 0; \
+ ASTOBJ_WRLOCK(object); \
+ if (__builtin_expect((object)->refcount > 0, 1)) \
+ newcount = --((object)->refcount); \
+ else \
+ ast_log(LOG_WARNING, "Unreferencing unreferenced (object)!\n"); \
+ ASTOBJ_UNLOCK(object); \
+ if (newcount == 0) { \
+ ast_mutex_destroy(&(object)->_lock); \
+ destructor((object)); \
+ } \
+ (object) = NULL; \
+ } while(0)
+
+/*! \brief Mark an ASTOBJ by adding the #ASTOBJ_FLAG_MARKED flag to its objflags mask.
+ * \param object A pointer to the object to operate on.
+ *
+ * This macro "marks" an object. Marked objects can later be unlinked from a container using
+ * #ASTOBJ_CONTAINER_PRUNE_MARKED().
+ *
+ */
+#define ASTOBJ_MARK(object) \
+ do { \
+ ASTOBJ_WRLOCK(object); \
+ (object)->objflags |= ASTOBJ_FLAG_MARKED; \
+ ASTOBJ_UNLOCK(object); \
+ } while(0)
+
+/*! \brief Unmark an ASTOBJ by subtracting the #ASTOBJ_FLAG_MARKED flag from its objflags mask.
+ * \param object A pointer to the object to operate on.
+ */
+#define ASTOBJ_UNMARK(object) \
+ do { \
+ ASTOBJ_WRLOCK(object); \
+ (object)->objflags &= ~ASTOBJ_FLAG_MARKED; \
+ ASTOBJ_UNLOCK(object); \
+ } while(0)
+
+/*! \brief Initialize an object.
+ * \param object A pointer to the object to operate on.
+ *
+ * \note This should only be used on objects that support locking (objects
+ * created with #ASTOBJ_COMPONENTS() or #ASTOBJ_COMPONENTS_FULL())
+ */
+#define ASTOBJ_INIT(object) \
+ do { \
+ ast_mutex_init(&(object)->_lock); \
+ object->name[0] = '\0'; \
+ object->refcount = 1; \
+ } while(0)
+
+/* Containers for objects -- current implementation is linked lists, but
+ should be able to be converted to hashes relatively easily */
+
+/*! \brief Lock an ASTOBJ_CONTAINER for reading.
+ */
+#define ASTOBJ_CONTAINER_RDLOCK(container) ast_mutex_lock(&(container)->_lock)
+
+/*! \brief Lock an ASTOBJ_CONTAINER for writing.
+ */
+#define ASTOBJ_CONTAINER_WRLOCK(container) ast_mutex_lock(&(container)->_lock)
+
+/*! \brief Unlock an ASTOBJ_CONTAINER. */
+#define ASTOBJ_CONTAINER_UNLOCK(container) ast_mutex_unlock(&(container)->_lock)
+
+#ifdef ASTOBJ_CONTAINER_HASHMODEL
+#error "Hash model for object containers not yet implemented!"
+#else
+/* Linked lists */
+
+/*! \brief Create a container for ASTOBJs (without locking support).
+ *
+ * \param type The type of objects the container will hold.
+ * \param hashes Currently unused.
+ * \param buckets Currently unused.
+ *
+ * This macro is used to create a container for ASTOBJs without locking
+ * support.
+ *
+ * <b>Sample Usage:</b>
+ * \code
+ * struct sample_struct_nolock_container {
+ * ASTOBJ_CONTAINER_COMPONENTS_NOLOCK_FULL(struct sample_struct,1,1);
+ * };
+ * \endcode
+ */
+#define ASTOBJ_CONTAINER_COMPONENTS_NOLOCK_FULL(type,hashes,buckets) \
+ type *head
+
+/*! \brief Initialize a container.
+ *
+ * \param container A pointer to the container to initialize.
+ * \param hashes Currently unused.
+ * \param buckets Currently unused.
+ *
+ * This macro initializes a container. It should only be used on containers
+ * that support locking.
+ *
+ * <b>Sample Usage:</b>
+ * \code
+ * struct sample_struct_container {
+ * ASTOBJ_CONTAINER_COMPONENTS_FULL(struct sample_struct,1,1);
+ * } container;
+ *
+ * int func()
+ * {
+ * ASTOBJ_CONTAINER_INIT_FULL(&container,1,1);
+ * }
+ * \endcode
+ */
+#define ASTOBJ_CONTAINER_INIT_FULL(container,hashes,buckets) \
+ do { \
+ ast_mutex_init(&(container)->_lock); \
+ } while(0)
+
+/*! \brief Destroy a container.
+ *
+ * \param container A pointer to the container to destroy.
+ * \param hashes Currently unused.
+ * \param buckets Currently unused.
+ *
+ * This macro frees up resources used by a container. It does not operate on
+ * the objects in the container. To unlink the objects from the container use
+ * #ASTOBJ_CONTAINER_DESTROYALL().
+ *
+ * \note This macro should only be used on containers with locking support.
+ */
+#define ASTOBJ_CONTAINER_DESTROY_FULL(container,hashes,buckets) \
+ do { \
+ ast_mutex_destroy(&(container)->_lock); \
+ } while(0)
+
+/*! \brief Iterate through the objects in a container.
+ *
+ * \param container A pointer to the container to traverse.
+ * \param continue A condition to allow the traversal to continue.
+ * \param eval A statement to evaluate in the iteration loop.
+ *
+ * This is macro is a little complicated, but it may help to think of it as a
+ * loop. Basically it iterates through the specfied containter as long as the
+ * condition is met. Two variables, iterator and next, are provided for use in
+ * your \p eval statement. See the sample code for an example.
+ *
+ * <b>Sample Usage:</b>
+ * \code
+ * ASTOBJ_CONTAINER_TRAVERSE(&sample_container,1, {
+ * ASTOBJ_RDLOCK(iterator);
+ * printf("Currently iterating over '%s'\n", iterator->name);
+ * ASTOBJ_UNLOCK(iterator);
+ * } );
+ * \endcode
+ *
+ * \code
+ * ASTOBJ_CONTAINER_TRAVERSE(&sample_container,1, sample_func(iterator));
+ * \endcode
+ */
+#define ASTOBJ_CONTAINER_TRAVERSE(container,continue,eval) \
+ do { \
+ typeof((container)->head) iterator; \
+ typeof((container)->head) next; \
+ ASTOBJ_CONTAINER_RDLOCK(container); \
+ next = (container)->head; \
+ while((continue) && (iterator = next)) { \
+ next = iterator->next[0]; \
+ eval; \
+ } \
+ ASTOBJ_CONTAINER_UNLOCK(container); \
+ } while(0)
+
+/*! \brief Find an object in a container.
+ *
+ * \param container A pointer to the container to search.
+ * \param namestr The name to search for.
+ *
+ * Use this function to find an object with the specfied name in a container.
+ *
+ * \note When the returned object is no longer in use, #ASTOBJ_UNREF() should
+ * be used to free the additional reference created by this macro.
+ *
+ * \return A new reference to the object located or NULL if nothing is found.
+ */
+#define ASTOBJ_CONTAINER_FIND(container,namestr) \
+ ({ \
+ typeof((container)->head) found = NULL; \
+ ASTOBJ_CONTAINER_TRAVERSE(container, !found, do { \
+ if (!(strcasecmp(iterator->name, (namestr)))) \
+ found = ASTOBJ_REF(iterator); \
+ } while (0)); \
+ found; \
+ })
+
+/*! \brief Find an object in a container.
+ *
+ * \param container A pointer to the container to search.
+ * \param data The data to search for.
+ * \param field The field/member of the container's objects to search.
+ * \param hashfunc The hash function to use, currently not implemented.
+ * \param hashoffset The hash offset to use, currently not implemented.
+ * \param comparefunc The function used to compare the field and data values.
+ *
+ * This macro iterates through a container passing the specified field and data
+ * elements to the specified comparefunc. The function should return 0 when a match is found.
+ *
+ * \note When the returned object is no longer in use, #ASTOBJ_UNREF() should
+ * be used to free the additional reference created by this macro.
+ *
+ * \return A pointer to the object located or NULL if nothing is found.
+ */
+#define ASTOBJ_CONTAINER_FIND_FULL(container,data,field,hashfunc,hashoffset,comparefunc) \
+ ({ \
+ typeof((container)->head) found = NULL; \
+ ASTOBJ_CONTAINER_TRAVERSE(container, !found, do { \
+ ASTOBJ_RDLOCK(iterator); \
+ if (!(comparefunc(iterator->field, (data)))) { \
+ found = ASTOBJ_REF(iterator); \
+ } \
+ ASTOBJ_UNLOCK(iterator); \
+ } while (0)); \
+ found; \
+ })
+
+/*! \brief Empty a container.
+ *
+ * \param container A pointer to the container to operate on.
+ * \param destructor A destructor function to call on each object.
+ *
+ * This macro loops through a container removing all the items from it using
+ * #ASTOBJ_UNREF(). This does not destroy the container itself, use
+ * #ASTOBJ_CONTAINER_DESTROY() for that.
+ *
+ * \note If any object in the container is only referenced by the container,
+ * the destructor will be called for that object once it has been removed.
+ */
+#define ASTOBJ_CONTAINER_DESTROYALL(container,destructor) \
+ do { \
+ typeof((container)->head) iterator; \
+ ASTOBJ_CONTAINER_WRLOCK(container); \
+ while((iterator = (container)->head)) { \
+ (container)->head = (iterator)->next[0]; \
+ ASTOBJ_UNREF(iterator,destructor); \
+ } \
+ ASTOBJ_CONTAINER_UNLOCK(container); \
+ } while(0)
+
+/*! \brief Remove an object from a container.
+ *
+ * \param container A pointer to the container to operate on.
+ * \param obj A pointer to the object to remove.
+ *
+ * This macro iterates through a container and removes the specfied object if
+ * it exists in the container.
+ *
+ * \note This macro does not destroy any objects, it simply unlinks
+ * them from the list. No destructors are called.
+ *
+ * \return The container's reference to the removed object or NULL if no
+ * matching object was found.
+ */
+#define ASTOBJ_CONTAINER_UNLINK(container,obj) \
+ ({ \
+ typeof((container)->head) found = NULL; \
+ typeof((container)->head) prev = NULL; \
+ ASTOBJ_CONTAINER_TRAVERSE(container, !found, do { \
+ if (iterator == obj) { \
+ found = iterator; \
+ found->next[0] = NULL; \
+ ASTOBJ_CONTAINER_WRLOCK(container); \
+ if (prev) \
+ prev->next[0] = next; \
+ else \
+ (container)->head = next; \
+ ASTOBJ_CONTAINER_UNLOCK(container); \
+ } \
+ prev = iterator; \
+ } while (0)); \
+ found; \
+ })
+
+/*! \brief Find and remove an object from a container.
+ *
+ * \param container A pointer to the container to operate on.
+ * \param namestr The name of the object to remove.
+ *
+ * This macro iterates through a container and removes the first object with
+ * the specfied name from the container.
+ *
+ * \note This macro does not destroy any objects, it simply unlinks
+ * them. No destructors are called.
+ *
+ * \return The container's reference to the removed object or NULL if no
+ * matching object was found.
+ */
+#define ASTOBJ_CONTAINER_FIND_UNLINK(container,namestr) \
+ ({ \
+ typeof((container)->head) found = NULL; \
+ typeof((container)->head) prev = NULL; \
+ ASTOBJ_CONTAINER_TRAVERSE(container, !found, do { \
+ if (!(strcasecmp(iterator->name, (namestr)))) { \
+ found = iterator; \
+ found->next[0] = NULL; \
+ ASTOBJ_CONTAINER_WRLOCK(container); \
+ if (prev) \
+ prev->next[0] = next; \
+ else \
+ (container)->head = next; \
+ ASTOBJ_CONTAINER_UNLOCK(container); \
+ } \
+ prev = iterator; \
+ } while (0)); \
+ found; \
+ })
+
+/*! \brief Find and remove an object in a container.
+ *
+ * \param container A pointer to the container to search.
+ * \param data The data to search for.
+ * \param field The field/member of the container's objects to search.
+ * \param hashfunc The hash function to use, currently not implemented.
+ * \param hashoffset The hash offset to use, currently not implemented.
+ * \param comparefunc The function used to compare the field and data values.
+ *
+ * This macro iterates through a container passing the specified field and data
+ * elements to the specified comparefunc. The function should return 0 when a match is found.
+ * If a match is found it is removed from the list.
+ *
+ * \note This macro does not destroy any objects, it simply unlinks
+ * them. No destructors are called.
+ *
+ * \return The container's reference to the removed object or NULL if no match
+ * was found.
+ */
+#define ASTOBJ_CONTAINER_FIND_UNLINK_FULL(container,data,field,hashfunc,hashoffset,comparefunc) \
+ ({ \
+ typeof((container)->head) found = NULL; \
+ typeof((container)->head) prev = NULL; \
+ ASTOBJ_CONTAINER_TRAVERSE(container, !found, do { \
+ ASTOBJ_RDLOCK(iterator); \
+ if (!(comparefunc(iterator->field, (data)))) { \
+ found = iterator; \
+ found->next[0] = NULL; \
+ ASTOBJ_CONTAINER_WRLOCK(container); \
+ if (prev) \
+ prev->next[0] = next; \
+ else \
+ (container)->head = next; \
+ ASTOBJ_CONTAINER_UNLOCK(container); \
+ } \
+ ASTOBJ_UNLOCK(iterator); \
+ prev = iterator; \
+ } while (0)); \
+ found; \
+ })
+
+/*! \brief Add an object to the end of a container.
+ *
+ * \param container A pointer to the container to operate on.
+ * \param newobj A pointer to the object to be added.
+ *
+ * This macro adds an object to the end of a container.
+ */
+#define ASTOBJ_CONTAINER_LINK_END(container,newobj) \
+ do { \
+ typeof((container)->head) iterator; \
+ typeof((container)->head) next; \
+ typeof((container)->head) prev; \
+ ASTOBJ_CONTAINER_RDLOCK(container); \
+ prev = NULL; \
+ next = (container)->head; \
+ while((iterator = next)) { \
+ next = iterator->next[0]; \
+ prev = iterator; \
+ } \
+ if(prev) { \
+ ASTOBJ_CONTAINER_WRLOCK((container)); \
+ prev->next[0] = ASTOBJ_REF(newobj); \
+ (newobj)->next[0] = NULL; \
+ ASTOBJ_CONTAINER_UNLOCK((container)); \
+ } else { \
+ ASTOBJ_CONTAINER_LINK_START((container),(newobj)); \
+ } \
+ ASTOBJ_CONTAINER_UNLOCK((container)); \
+ } while(0)
+
+/*! \brief Add an object to the front of a container.
+ *
+ * \param container A pointer to the container to operate on.
+ * \param newobj A pointer to the object to be added.
+ *
+ * This macro adds an object to the start of a container.
+ */
+#define ASTOBJ_CONTAINER_LINK_START(container,newobj) \
+ do { \
+ ASTOBJ_CONTAINER_WRLOCK(container); \
+ (newobj)->next[0] = (container)->head; \
+ (container)->head = ASTOBJ_REF(newobj); \
+ ASTOBJ_CONTAINER_UNLOCK(container); \
+ } while(0)
+
+/*! \brief Remove an object from the front of a container.
+ *
+ * \param container A pointer to the container to operate on.
+ *
+ * This macro removes the first object in a container.
+ *
+ * \note This macro does not destroy any objects, it simply unlinks
+ * them from the list. No destructors are called.
+ *
+ * \return The container's reference to the removed object or NULL if no
+ * matching object was found.
+ */
+#define ASTOBJ_CONTAINER_UNLINK_START(container) \
+ ({ \
+ typeof((container)->head) found = NULL; \
+ ASTOBJ_CONTAINER_WRLOCK(container); \
+ if((container)->head) { \
+ found = (container)->head; \
+ (container)->head = (container)->head->next[0]; \
+ found->next[0] = NULL; \
+ } \
+ ASTOBJ_CONTAINER_UNLOCK(container); \
+ found; \
+ })
+
+/*! \brief Prune marked objects from a container.
+ *
+ * \param container A pointer to the container to prune.
+ * \param destructor A destructor function to call on each marked object.
+ *
+ * This macro iterates through the specfied container and prunes any marked
+ * objects executing the specfied destructor if necessary.
+ */
+#define ASTOBJ_CONTAINER_PRUNE_MARKED(container,destructor) \
+ do { \
+ typeof((container)->head) prev = NULL; \
+ ASTOBJ_CONTAINER_TRAVERSE(container, 1, do { \
+ ASTOBJ_RDLOCK(iterator); \
+ if (iterator->objflags & ASTOBJ_FLAG_MARKED) { \
+ ASTOBJ_CONTAINER_WRLOCK(container); \
+ if (prev) \
+ prev->next[0] = next; \
+ else \
+ (container)->head = next; \
+ ASTOBJ_CONTAINER_UNLOCK(container); \
+ ASTOBJ_UNLOCK(iterator); \
+ ASTOBJ_UNREF(iterator,destructor); \
+ continue; \
+ } \
+ ASTOBJ_UNLOCK(iterator); \
+ prev = iterator; \
+ } while (0)); \
+ } while(0)
+
+/*! \brief Add an object to a container.
+ *
+ * \param container A pointer to the container to operate on.
+ * \param newobj A pointer to the object to be added.
+ * \param data Currently unused.
+ * \param field Currently unused.
+ * \param hashfunc Currently unused.
+ * \param hashoffset Currently unused.
+ * \param comparefunc Currently unused.
+ *
+ * Currently this function adds an object to the head of the list. One day it
+ * will support adding objects atthe position specified using the various
+ * options this macro offers.
+ */
+#define ASTOBJ_CONTAINER_LINK_FULL(container,newobj,data,field,hashfunc,hashoffset,comparefunc) \
+ do { \
+ ASTOBJ_CONTAINER_WRLOCK(container); \
+ (newobj)->next[0] = (container)->head; \
+ (container)->head = ASTOBJ_REF(newobj); \
+ ASTOBJ_CONTAINER_UNLOCK(container); \
+ } while(0)
+
+#endif /* List model */
+
+/* Common to hash and linked list models */
+
+/*! \brief Create a container for ASTOBJs (without locking support).
+ *
+ * \param type The type of objects the container will hold.
+ *
+ * This macro is used to create a container for ASTOBJs without locking
+ * support.
+ *
+ * <b>Sample Usage:</b>
+ * \code
+ * struct sample_struct_nolock_container {
+ * ASTOBJ_CONTAINER_COMPONENTS_NOLOCK(struct sample_struct);
+ * };
+ * \endcode
+ */
+#define ASTOBJ_CONTAINER_COMPONENTS_NOLOCK(type) \
+ ASTOBJ_CONTAINER_COMPONENTS_NOLOCK_FULL(type,1,ASTOBJ_DEFAULT_BUCKETS)
+
+
+/*! \brief Create a container for ASTOBJs (with locking support).
+ *
+ * \param type The type of objects the container will hold.
+ *
+ * This macro is used to create a container for ASTOBJs with locking support.
+ *
+ * <b>Sample Usage:</b>
+ * \code
+ * struct sample_struct_container {
+ * ASTOBJ_CONTAINER_COMPONENTS(struct sample_struct);
+ * };
+ * \endcode
+ */
+#define ASTOBJ_CONTAINER_COMPONENTS(type) \
+ ast_mutex_t _lock; \
+ ASTOBJ_CONTAINER_COMPONENTS_NOLOCK(type)
+
+/*! \brief Initialize a container.
+ *
+ * \param container A pointer to the container to initialize.
+ *
+ * This macro initializes a container. It should only be used on containers
+ * that support locking.
+ *
+ * <b>Sample Usage:</b>
+ * \code
+ * struct sample_struct_container {
+ * ASTOBJ_CONTAINER_COMPONENTS(struct sample_struct);
+ * } container;
+ *
+ * int func()
+ * {
+ * ASTOBJ_CONTAINER_INIT(&container);
+ * }
+ * \endcode
+ */
+#define ASTOBJ_CONTAINER_INIT(container) \
+ ASTOBJ_CONTAINER_INIT_FULL(container,1,ASTOBJ_DEFAULT_BUCKETS)
+
+/*! \brief Destroy a container.
+ *
+ * \param container A pointer to the container to destory.
+ *
+ * This macro frees up resources used by a container. It does not operate on
+ * the objects in the container. To unlink the objects from the container use
+ * #ASTOBJ_CONTAINER_DESTROYALL().
+ *
+ * \note This macro should only be used on containers with locking support.
+ */
+#define ASTOBJ_CONTAINER_DESTROY(container) \
+ ASTOBJ_CONTAINER_DESTROY_FULL(container,1,ASTOBJ_DEFAULT_BUCKETS)
+
+/*! \brief Add an object to a container.
+ *
+ * \param container A pointer to the container to operate on.
+ * \param newobj A pointer to the object to be added.
+ *
+ * Currently this macro adds an object to the head of a container. One day it
+ * should add an object in alphabetical order.
+ */
+#define ASTOBJ_CONTAINER_LINK(container,newobj) \
+ ASTOBJ_CONTAINER_LINK_FULL(container,newobj,(newobj)->name,name,ASTOBJ_DEFAULT_HASH,0,strcasecmp)
+
+/*! \brief Mark all the objects in a container.
+ * \param container A pointer to the container to operate on.
+ */
+#define ASTOBJ_CONTAINER_MARKALL(container) \
+ ASTOBJ_CONTAINER_TRAVERSE(container, 1, ASTOBJ_MARK(iterator))
+
+/*! \brief Unmark all the objects in a container.
+ * \param container A pointer to the container to operate on.
+ */
+#define ASTOBJ_CONTAINER_UNMARKALL(container) \
+ ASTOBJ_CONTAINER_TRAVERSE(container, 1, ASTOBJ_UNMARK(iterator))
+
+/*! \brief Dump information about an object into a string.
+ *
+ * \param s A pointer to the string buffer to use.
+ * \param slen The length of s.
+ * \param obj A pointer to the object to dump.
+ *
+ * This macro dumps a text representation of the name, objectflags, and
+ * refcount fields of an object to the specfied string buffer.
+ */
+#define ASTOBJ_DUMP(s,slen,obj) \
+ snprintf((s),(slen),"name: %s\nobjflags: %d\nrefcount: %d\n\n", (obj)->name, (obj)->objflags, (obj)->refcount);
+
+/*! \brief Dump information about all the objects in a container to a file descriptor.
+ *
+ * \param fd The file descriptor to write to.
+ * \param s A string buffer, same as #ASTOBJ_DUMP().
+ * \param slen The length of s, same as #ASTOBJ_DUMP().
+ * \param container A pointer to the container to dump.
+ *
+ * This macro dumps a text representation of the name, objectflags, and
+ * refcount fields of all the objects in a container to the specified file
+ * descriptor.
+ */
+#define ASTOBJ_CONTAINER_DUMP(fd,s,slen,container) \
+ ASTOBJ_CONTAINER_TRAVERSE(container, 1, do { ASTOBJ_DUMP(s,slen,iterator); ast_cli(fd, s); } while(0))
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _ASTERISK_ASTOBJ_H */
diff --git a/trunk/include/asterisk/astobj2.h b/trunk/include/asterisk/astobj2.h
new file mode 100644
index 000000000..b02b6cba8
--- /dev/null
+++ b/trunk/include/asterisk/astobj2.h
@@ -0,0 +1,568 @@
+/*
+ * astobj2 - replacement containers for asterisk data structures.
+ *
+ * Copyright (C) 2006 Marta Carbone, Luigi Rizzo - Univ. di Pisa, Italy
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+#ifndef _ASTERISK_ASTOBJ2_H
+#define _ASTERISK_ASTOBJ2_H
+
+/*! \file
+ * \ref AstObj2
+ *
+ * \page AstObj2 Object Model implementing objects and containers.
+
+This module implements an abstraction for objects (with locks and
+reference counts), and containers for these user-defined objects,
+also supporting locking, reference counting and callbacks.
+
+The internal implementation of objects and containers is opaque to the user,
+so we can use different data structures as needs arise.
+
+\section AstObj2_UsageObjects USAGE - OBJECTS
+
+An ao2 object is a block of memory that the user code can access,
+and for which the system keeps track (with a bit of help from the
+programmer) of the number of references around. When an object has
+no more references (refcount == 0), it is destroyed, by first
+invoking whatever 'destructor' function the programmer specifies
+(it can be NULL if none is necessary), and then freeing the memory.
+This way objects can be shared without worrying who is in charge
+of freeing them.
+As an additional feature, ao2 objects are associated to individual
+locks.
+
+Creating an object requires the size of the object and
+and a pointer to the destructor function:
+
+ struct foo *o;
+
+ o = ao2_alloc(sizeof(struct foo), my_destructor_fn);
+
+The value returned points to the user-visible portion of the objects
+(user-data), but is also used as an identifier for all object-related
+operations such as refcount and lock manipulations.
+
+On return from ao2_alloc():
+
+ - the object has a refcount = 1;
+ - the memory for the object is allocated dynamically and zeroed;
+ - we cannot realloc() the object itself;
+ - we cannot call free(o) to dispose of the object. Rather, we
+ tell the system that we do not need the reference anymore:
+
+ ao2_ref(o, -1)
+
+ causing the destructor to be called (and then memory freed) when
+ the refcount goes to 0. This is also available as ao2_unref(o),
+ and returns NULL as a convenience, so you can do things like
+
+ o = ao2_unref(o);
+
+ and clean the original pointer to prevent errors.
+
+- ao2_ref(o, +1) can be used to modify the refcount on the
+ object in case we want to pass it around.
+
+- ao2_lock(obj), ao2_unlock(obj), ao2_trylock(obj) can be used
+ to manipulate the lock associated with the object.
+
+
+\section AstObj2_UsageContainers USAGE - CONTAINERS
+
+An ao2 container is an abstract data structure where we can store
+ao2 objects, search them (hopefully in an efficient way), and iterate
+or apply a callback function to them. A container is just an ao2 object
+itself.
+
+A container must first be allocated, specifying the initial
+parameters. At the moment, this is done as follows:
+
+ <b>Sample Usage:</b>
+ \code
+
+ struct ao2_container *c;
+
+ c = ao2_container_alloc(MAX_BUCKETS, my_hash_fn, my_cmp_fn);
+ \endcode
+
+where
+
+- MAX_BUCKETS is the number of buckets in the hash table,
+- my_hash_fn() is the (user-supplied) function that returns a
+ hash key for the object (further reduced modulo MAX_BUCKETS
+ by the container's code);
+- my_cmp_fn() is the default comparison function used when doing
+ searches on the container,
+
+A container knows little or nothing about the objects it stores,
+other than the fact that they have been created by ao2_alloc().
+All knowledge of the (user-defined) internals of the objects
+is left to the (user-supplied) functions passed as arguments
+to ao2_container_alloc().
+
+If we want to insert an object in a container, we should
+initialize its fields -- especially, those used by my_hash_fn() --
+to compute the bucket to use.
+Once done, we can link an object to a container with
+
+ ao2_link(c, o);
+
+The function returns NULL in case of errors (and the object
+is not inserted in the container). Other values mean success
+(we are not supposed to use the value as a pointer to anything).
+
+\note While an object o is in a container, we expect that
+my_hash_fn(o) will always return the same value. The function
+does not lock the object to be computed, so modifications of
+those fields that affect the computation of the hash should
+be done by extracting the object from the container, and
+reinserting it after the change (this is not terribly expensive).
+
+\note A container with a single buckets is effectively a linked
+list. However there is no ordering among elements.
+
+- \ref AstObj2_Containers
+- \ref astobj2.h All documentation for functions and data structures
+
+ */
+
+/*! \brief
+ * Typedef for an object destructor. This is called just before freeing
+ * the memory for the object. It is passed a pointer to the user-defined
+ * data of the object.
+ */
+typedef void (*ao2_destructor_fn)(void *);
+
+
+/*! \brief
+ * Allocate and initialize an object.
+ *
+ * \param data_size The sizeof() of the user-defined structure.
+ * \param destructor_fn The destructor function (can be NULL)
+ * \return A pointer to user-data.
+ *
+ * Allocates a struct astobj2 with sufficient space for the
+ * user-defined structure.
+ * \note
+ * - storage is zeroed; XXX maybe we want a flag to enable/disable this.
+ * - the refcount of the object just created is 1
+ * - the returned pointer cannot be free()'d or realloc()'ed;
+ * rather, we just call ao2_ref(o, -1);
+ */
+void *ao2_alloc(const size_t data_size, ao2_destructor_fn destructor_fn);
+
+/*! \brief
+ * Reference/unreference an object and return the old refcount.
+ *
+ * \param o A pointer to the object
+ * \param delta Value to add to the reference counter.
+ * \return The value of the reference counter before the operation.
+ *
+ * Increase/decrease the reference counter according
+ * the value of delta.
+ *
+ * If the refcount goes to zero, the object is destroyed.
+ *
+ * \note The object must not be locked by the caller of this function, as
+ * it is invalid to try to unlock it after releasing the reference.
+ *
+ * \note if we know the pointer to an object, it is because we
+ * have a reference count to it, so the only case when the object
+ * can go away is when we release our reference, and it is
+ * the last one in existence.
+ */
+int ao2_ref(void *o, int delta);
+
+/*! \brief
+ * Lock an object.
+ *
+ * \param a A pointer to the object we want lock.
+ * \return 0 on success, other values on error.
+ */
+int ao2_lock(void *a);
+
+/*! \brief
+ * Unlock an object.
+ *
+ * \param a A pointer to the object we want unlock.
+ * \return 0 on success, other values on error.
+ */
+int ao2_unlock(void *a);
+
+/*!
+ *
+ \page AstObj2_Containers AstObj2 Containers
+
+Containers are data structures meant to store several objects,
+and perform various operations on them.
+Internally, objects are stored in lists, hash tables or other
+data structures depending on the needs.
+
+\note NOTA BENE: at the moment the only container we support is the
+ hash table and its degenerate form, the list.
+
+Operations on container include:
+
+ - c = \b ao2_container_alloc(size, cmp_fn, hash_fn)
+ allocate a container with desired size and default compare
+ and hash function
+
+ - \b ao2_find(c, arg, flags)
+ returns zero or more element matching a given criteria
+ (specified as arg). Flags indicate how many results we
+ want (only one or all matching entries), and whether we
+ should unlink the object from the container.
+
+ - \b ao2_callback(c, flags, fn, arg)
+ apply fn(obj, arg) to all objects in the container.
+ Similar to find. fn() can tell when to stop, and
+ do anything with the object including unlinking it.
+ Note that the entire operation is run with the container
+ locked, so noone else can change its content while we work on it.
+ However, we pay this with the fact that doing
+ anything blocking in the callback keeps the container
+ blocked.
+ The mechanism is very flexible because the callback function fn()
+ can do basically anything e.g. counting, deleting records, etc.
+ possibly using arg to store the results.
+
+ - \b iterate on a container
+ this is done with the following sequence
+
+\code
+
+ struct ao2_container *c = ... // our container
+ struct ao2_iterator i;
+ void *o;
+
+ i = ao2_iterator_init(c, flags);
+
+ while ( (o = ao2_iterator_next(&i)) ) {
+ ... do something on o ...
+ ao2_ref(o, -1);
+ }
+\endcode
+
+ The difference with the callback is that the control
+ on how to iterate is left to us.
+
+ - \b ao2_ref(c, -1)
+ dropping a reference to a container destroys it, very simple!
+
+Containers are ao2 objects themselves, and this is why their
+implementation is simple too.
+
+Before declaring containers, we need to declare the types of the
+arguments passed to the constructor - in turn, this requires
+to define callback and hash functions and their arguments.
+
+- \ref AstObj2
+- \ref astobj2.h
+ */
+
+/*! \brief
+ * Type of a generic callback function
+ * \param obj pointer to the (user-defined part) of an object.
+ * \param arg callback argument from ao2_callback()
+ * \param flags flags from ao2_callback()
+ *
+ * The return values are a combination of enum _cb_results.
+ * Callback functions are used to search or manipulate objects in a container,
+ */
+typedef int (ao2_callback_fn)(void *obj, void *arg, int flags);
+
+/*! \brief a very common callback is one that matches by address. */
+ao2_callback_fn ao2_match_by_addr;
+
+/*! \brief
+ * A callback function will return a combination of CMP_MATCH and CMP_STOP.
+ * The latter will terminate the search in a container.
+ */
+enum _cb_results {
+ CMP_MATCH = 0x1, /*!< the object matches the request */
+ CMP_STOP = 0x2, /*!< stop the search now */
+};
+
+/*! \brief
+ * Flags passed to ao2_callback() and ao2_hash_fn() to modify its behaviour.
+ */
+enum search_flags {
+ /*! Unlink the object for which the callback function
+ * returned CMP_MATCH . This is the only way to extract
+ * objects from a container. */
+ OBJ_UNLINK = (1 << 0),
+ /*! On match, don't return the object hence do not increase
+ * its refcount. */
+ OBJ_NODATA = (1 << 1),
+ /*! Don't stop at the first match in ao2_callback()
+ * \note This is not fully implemented. */
+ OBJ_MULTIPLE = (1 << 2),
+ /*! obj is an object of the same type as the one being searched for,
+ * so use the object's hash function for optimized searching.
+ * The search function is unaffected (i.e. use the one passed as
+ * argument, or match_by_addr if none specified). */
+ OBJ_POINTER = (1 << 3),
+};
+
+/*!
+ * Type of a generic function to generate a hash value from an object.
+ * flags is ignored at the moment. Eventually, it will include the
+ * value of OBJ_POINTER passed to ao2_callback().
+ */
+typedef int (ao2_hash_fn)(const void *obj, const int flags);
+
+/*! \name Object Containers
+ * Here start declarations of containers.
+ */
+/*@{ */
+struct ao2_container;
+
+/*! \brief
+ * Allocate and initialize a container
+ * with the desired number of buckets.
+ *
+ * We allocate space for a struct astobj_container, struct container
+ * and the buckets[] array.
+ *
+ * \param n_buckets Number of buckets for hash
+ * \param hash_fn Pointer to a function computing a hash value.
+ * \param cmp_fn Pointer to a function comparating key-value
+ * with a string. (can be NULL)
+ * \return A pointer to a struct container.
+ *
+ * destructor is set implicitly.
+ */
+struct ao2_container *ao2_container_alloc(const uint n_buckets,
+ ao2_hash_fn *hash_fn, ao2_callback_fn *cmp_fn);
+
+/*! \brief
+ * Returns the number of elements in a container.
+ */
+int ao2_container_count(struct ao2_container *c);
+/*@} */
+
+/*! \name Object Management
+ * Here we have functions to manage objects.
+ *
+ * We can use the functions below on any kind of
+ * object defined by the user.
+ */
+/*@{ */
+
+/*!
+ * \brief Add an object to a container.
+ *
+ * \param c the container to operate on.
+ * \param newobj the object to be added.
+ *
+ * \retval NULL on errors
+ * \retval newobj on success.
+ *
+ * This function inserts an object in a container according its key.
+ *
+ * \note Remember to set the key before calling this function.
+ *
+ * \note This function automatically increases the reference count to account
+ * for the reference that the container now holds to the object.
+ */
+void *ao2_link(struct ao2_container *c, void *newobj);
+
+/*!
+ * \brief Remove an object from the container
+ *
+ * \arg c the container
+ * \arg obj the object to unlink
+ *
+ * \retval NULL, always
+ *
+ * \note The object requested to be unlinked must be valid. However, if it turns
+ * out that it is not in the container, this function is still safe to
+ * be called.
+ *
+ * \note If the object gets unlinked from the container, the container's
+ * reference to the object will be automatically released.
+ */
+void *ao2_unlink(struct ao2_container *c, void *obj);
+
+/*! \brief Used as return value if the flag OBJ_MULTIPLE is set */
+struct ao2_list {
+ struct ao2_list *next;
+ void *obj; /* pointer to the user portion of the object */
+};
+/*@} */
+
+/*! \brief
+ * ao2_callback() is a generic function that applies cb_fn() to all objects
+ * in a container, as described below.
+ *
+ * \param c A pointer to the container to operate on.
+ * \param arg passed to the callback.
+ * \param flags A set of flags specifying the operation to perform,
+ partially used by the container code, but also passed to
+ the callback.
+ * \return A pointer to the object found/marked,
+ * a pointer to a list of objects matching comparison function,
+ * NULL if not found.
+ *
+ * If the function returns any objects, their refcount is incremented,
+ * and the caller is in charge of decrementing them once done.
+ * Also, in case of multiple values returned, the list used
+ * to store the objects must be freed by the caller.
+ *
+ * Typically, ao2_callback() is used for two purposes:
+ * - to perform some action (including removal from the container) on one
+ * or more objects; in this case, cb_fn() can modify the object itself,
+ * and to perform deletion should set CMP_MATCH on the matching objects,
+ * and have OBJ_UNLINK set in flags.
+ * - to look for a specific object in a container; in this case, cb_fn()
+ * should not modify the object, but just return a combination of
+ * CMP_MATCH and CMP_STOP on the desired object.
+ * Other usages are also possible, of course.
+
+ * This function searches through a container and performs operations
+ * on objects according on flags passed.
+ * XXX describe better
+ * The comparison is done calling the compare function set implicitly.
+ * The p pointer can be a pointer to an object or to a key,
+ * we can say this looking at flags value.
+ * If p points to an object we will search for the object pointed
+ * by this value, otherwise we serch for a key value.
+ * If the key is not uniq we only find the first matching valued.
+ * If we use the OBJ_MARK flags, we mark all the objects matching
+ * the condition.
+ *
+ * The use of flags argument is the follow:
+ *
+ * OBJ_UNLINK unlinks the object found
+ * OBJ_NODATA on match, do return an object
+ * Callbacks use OBJ_NODATA as a default
+ * functions such as find() do
+ * OBJ_MULTIPLE return multiple matches
+ * Default for _find() is no.
+ * to a key (not yet supported)
+ * OBJ_POINTER the pointer is an object pointer
+ *
+ * In case we return a list, the callee must take care to destroy
+ * that list when no longer used.
+ *
+ * \note When the returned object is no longer in use, ao2_ref() should
+ * be used to free the additional reference possibly created by this function.
+ */
+void *ao2_callback(struct ao2_container *c,
+ enum search_flags flags,
+ ao2_callback_fn *cb_fn, void *arg);
+
+/*! ao2_find() is a short hand for ao2_callback(c, flags, c->cmp_fn, arg)
+ * XXX possibly change order of arguments ?
+ */
+void *ao2_find(struct ao2_container *c, void *arg, enum search_flags flags);
+
+/*! \brief
+ *
+ *
+ * When we need to walk through a container, we use
+ * ao2_iterator to keep track of the current position.
+ *
+ * Because the navigation is typically done without holding the
+ * lock on the container across the loop,
+ * objects can be inserted or deleted or moved
+ * while we work. As a consequence, there is no guarantee that
+ * the we manage to touch all the elements on the list, or it
+ * is possible that we touch the same object multiple times.
+ * However, within the current hash table container, the following is true:
+ * - It is not possible to miss an object in the container while iterating
+ * unless it gets added after the iteration begins and is added to a bucket
+ * that is before the one the current object is in. In this case, even if
+ * you locked the container around the entire iteration loop, you still would
+ * not see this object, because it would still be waiting on the container
+ * lock so that it can be added.
+ * - It would be extremely rare to see an object twice. The only way this can
+ * happen is if an object got unlinked from the container and added again
+ * during the same iteration. Furthermore, when the object gets added back,
+ * it has to be in the current or later bucket for it to be seen again.
+ *
+ * An iterator must be first initialized with ao2_iterator_init(),
+ * then we can use o = ao2_iterator_next() to move from one
+ * element to the next. Remember that the object returned by
+ * ao2_iterator_next() has its refcount incremented,
+ * and the reference must be explicitly released when done with it.
+ *
+ * Example:
+ *
+ * \code
+ *
+ * struct ao2_container *c = ... // the container we want to iterate on
+ * struct ao2_iterator i;
+ * struct my_obj *o;
+ *
+ * i = ao2_iterator_init(c, flags);
+ *
+ * while ( (o = ao2_iterator_next(&i)) ) {
+ * ... do something on o ...
+ * ao2_ref(o, -1);
+ * }
+ *
+ * \endcode
+ *
+ */
+
+/*! \brief
+ * The Astobj2 iterator
+ *
+ * \note You are not supposed to know the internals of an iterator!
+ * We would like the iterator to be opaque, unfortunately
+ * its size needs to be known if we want to store it around
+ * without too much trouble.
+ * Anyways...
+ * The iterator has a pointer to the container, and a flags
+ * field specifying various things e.g. whether the container
+ * should be locked or not while navigating on it.
+ * The iterator "points" to the current object, which is identified
+ * by three values:
+ *
+ * - a bucket number;
+ * - the object_id, which is also the container version number
+ * when the object was inserted. This identifies the object
+ * univoquely, however reaching the desired object requires
+ * scanning a list.
+ * - a pointer, and a container version when we saved the pointer.
+ * If the container has not changed its version number, then we
+ * can safely follow the pointer to reach the object in constant time.
+ *
+ * Details are in the implementation of ao2_iterator_next()
+ * A freshly-initialized iterator has bucket=0, version = 0.
+ */
+struct ao2_iterator {
+ /*! the container */
+ struct ao2_container *c;
+ /*! operation flags */
+ int flags;
+#define F_AO2I_DONTLOCK 1 /*!< don't lock when iterating */
+ /*! current bucket */
+ int bucket;
+ /*! container version */
+ uint c_version;
+ /*! pointer to the current object */
+ void *obj;
+ /*! container version when the object was created */
+ uint version;
+};
+
+struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags);
+
+void *ao2_iterator_next(struct ao2_iterator *a);
+
+/* extra functions */
+void ao2_bt(void); /* backtrace */
+#endif /* _ASTERISK_ASTOBJ2_H */
diff --git a/trunk/include/asterisk/astosp.h b/trunk/include/asterisk/astosp.h
new file mode 100644
index 000000000..d5c7da1a7
--- /dev/null
+++ b/trunk/include/asterisk/astosp.h
@@ -0,0 +1,31 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2005, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*!
+ * \file
+ * \brief Open Settlement Protocol (OSP)
+ */
+
+#ifndef _ASTERISK_OSP_H
+#define _ASTERISK_OSP_H
+
+#define AST_OSP_SUCCESS ((char*)"SUCCESS") /* Return status, success */
+#define AST_OSP_FAILED ((char*)"FAILED") /* Return status, failed */
+#define AST_OSP_ERROR ((char*)"ERROR") /* Return status, error */
+
+#endif /* _ASTERISK_OSP_H */
diff --git a/trunk/include/asterisk/audiohook.h b/trunk/include/asterisk/audiohook.h
new file mode 100644
index 000000000..5ef0ac294
--- /dev/null
+++ b/trunk/include/asterisk/audiohook.h
@@ -0,0 +1,210 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2007, Digium, Inc.
+ *
+ * Joshua Colp <jcolp@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief Audiohooks Architecture
+ */
+
+#ifndef _ASTERISK_AUDIOHOOK_H
+#define _ASTERISK_AUDIOHOOK_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/* these two are used in struct ast_audiohook */
+#include "asterisk/lock.h"
+#include "asterisk/linkedlists.h"
+
+#include "asterisk/slinfactory.h"
+
+enum ast_audiohook_type {
+ AST_AUDIOHOOK_TYPE_SPY = 0, /*!< Audiohook wants to receive audio */
+ AST_AUDIOHOOK_TYPE_WHISPER, /*!< Audiohook wants to provide audio to be mixed with existing audio */
+ AST_AUDIOHOOK_TYPE_MANIPULATE, /*!< Audiohook wants to manipulate the audio */
+};
+
+enum ast_audiohook_status {
+ AST_AUDIOHOOK_STATUS_NEW = 0, /*!< Audiohook was just created, not in use yet */
+ AST_AUDIOHOOK_STATUS_RUNNING, /*!< Audiohook is running on a channel */
+ AST_AUDIOHOOK_STATUS_SHUTDOWN, /*!< Audiohook is being shutdown */
+ AST_AUDIOHOOK_STATUS_DONE, /*!< Audiohook has shutdown and is not running on a channel any longer */
+};
+
+enum ast_audiohook_direction {
+ AST_AUDIOHOOK_DIRECTION_READ = 0, /*!< Reading audio in */
+ AST_AUDIOHOOK_DIRECTION_WRITE, /*!< Writing audio out */
+ AST_AUDIOHOOK_DIRECTION_BOTH, /*!< Both reading audio in and writing audio out */
+};
+
+enum ast_audiohook_flags {
+ AST_AUDIOHOOK_TRIGGER_MODE = (3 << 0), /*!< When audiohook should be triggered to do something */
+ AST_AUDIOHOOK_TRIGGER_READ = (1 << 0), /*!< Audiohook wants to be triggered when reading audio in */
+ AST_AUDIOHOOK_TRIGGER_WRITE = (2 << 0), /*!< Audiohook wants to be triggered when writing audio out */
+ AST_AUDIOHOOK_WANTS_DTMF = (1 << 1), /*!< Audiohook also wants to receive DTMF frames */
+};
+
+struct ast_audiohook;
+
+/*! \brief Callback function for manipulate audiohook type
+ * \param audiohook Audiohook structure
+ * \param chan Channel
+ * \param frame Frame of audio to manipulate
+ * \param direction Direction frame came from
+ * \return Returns 0 on success, -1 on failure
+ * \note An audiohook does not have any reference to a private data structure for manipulate types. It is up to the manipulate callback to store this data
+ * via it's own method. An example would be datastores.
+ */
+typedef int (*ast_audiohook_manipulate_callback)(struct ast_audiohook *audiohook, struct ast_channel *chan, struct ast_frame *frame, enum ast_audiohook_direction direction);
+
+struct ast_audiohook_options {
+ int read_volume; /*!< Volume adjustment on frames read from the channel the hook is on */
+ int write_volume; /*!< Volume adjustment on frames written to the channel the hook is on */
+};
+
+struct ast_audiohook {
+ ast_mutex_t lock; /*!< Lock that protects the audiohook structure */
+ ast_cond_t trigger; /*!< Trigger condition (if enabled) */
+ enum ast_audiohook_type type; /*!< Type of audiohook */
+ enum ast_audiohook_status status; /*!< Status of the audiohook */
+ const char *source; /*!< Who this audiohook ultimately belongs to */
+ unsigned int flags; /*!< Flags on the audiohook */
+ struct ast_slinfactory read_factory; /*!< Factory where frames read from the channel, or read from the whisper source will go through */
+ struct ast_slinfactory write_factory; /*!< Factory where frames written to the channel will go through */
+ int format; /*!< Format translation path is setup as */
+ struct ast_trans_pvt *trans_pvt; /*!< Translation path for reading frames */
+ ast_audiohook_manipulate_callback manipulate_callback; /*!< Manipulation callback */
+ struct ast_audiohook_options options; /*!< Applicable options */
+ AST_LIST_ENTRY(ast_audiohook) list; /*!< Linked list information */
+};
+
+struct ast_audiohook_list;
+
+/*! \brief Initialize an audiohook structure
+ * \param audiohook Audiohook structure
+ * \param type Type of audiohook to initialize this as
+ * \param source Who is initializing this audiohook
+ * \return Returns 0 on success, -1 on failure
+ */
+int ast_audiohook_init(struct ast_audiohook *audiohook, enum ast_audiohook_type type, const char *source);
+
+/*! \brief Destroys an audiohook structure
+ * \param audiohook Audiohook structure
+ * \return Returns 0 on success, -1 on failure
+ */
+int ast_audiohook_destroy(struct ast_audiohook *audiohook);
+
+/*! \brief Writes a frame into the audiohook structure
+ * \param audiohook Audiohook structure
+ * \param direction Direction the audio frame came from
+ * \param frame Frame to write in
+ * \return Returns 0 on success, -1 on failure
+ */
+int ast_audiohook_write_frame(struct ast_audiohook *audiohook, enum ast_audiohook_direction direction, struct ast_frame *frame);
+
+/*! \brief Reads a frame in from the audiohook structure
+ * \param audiohook Audiohook structure
+ * \param samples Number of samples wanted
+ * \param direction Direction the audio frame came from
+ * \param format Format of frame remote side wants back
+ * \return Returns frame on success, NULL on failure
+ */
+struct ast_frame *ast_audiohook_read_frame(struct ast_audiohook *audiohook, size_t samples, enum ast_audiohook_direction direction, int format);
+
+/*! \brief Attach audiohook to channel
+ * \param chan Channel
+ * \param audiohook Audiohook structure
+ * \return Returns 0 on success, -1 on failure
+ */
+int ast_audiohook_attach(struct ast_channel *chan, struct ast_audiohook *audiohook);
+
+/*! \brief Detach audiohook from channel
+ * \param audiohook Audiohook structure
+ * \return Returns 0 on success, -1 on failure
+ */
+int ast_audiohook_detach(struct ast_audiohook *audiohook);
+
+/*! \brief Detach audiohooks from list and destroy said list
+ * \param audiohook_list List of audiohooks
+ * \return Returns 0 on success, -1 on failure
+ */
+int ast_audiohook_detach_list(struct ast_audiohook_list *audiohook_list);
+
+/*!
+ * \brief Detach specified source audiohook from channel
+ *
+ * \param chan Channel to detach from
+ * \param source Name of source to detach
+ *
+ * \return Returns 0 on success, -1 on failure
+ *
+ * \note The channel does not need to be locked before calling this function.
+ */
+int ast_audiohook_detach_source(struct ast_channel *chan, const char *source);
+
+/*! \brief Pass a frame off to be handled by the audiohook core
+ * \param chan Channel that the list is coming off of
+ * \param audiohook_list List of audiohooks
+ * \param direction Direction frame is coming in from
+ * \param frame The frame itself
+ * \return Return frame on success, NULL on failure
+ */
+struct ast_frame *ast_audiohook_write_list(struct ast_channel *chan, struct ast_audiohook_list *audiohook_list, enum ast_audiohook_direction direction, struct ast_frame *frame);
+
+/*! \brief Wait for audiohook trigger to be triggered
+ * \param audiohook Audiohook to wait on
+ */
+void ast_audiohook_trigger_wait(struct ast_audiohook *audiohook);
+
+/*!
+ \brief Find out how many audiohooks from a certain source exist on a given channel, regardless of status.
+ \param chan The channel on which to find the spies
+ \param source The audiohook's source
+ \param type The type of audiohook
+ \return Return the number of audiohooks which are from the source specified
+
+ Note: Function performs nlocking.
+*/
+int ast_channel_audiohook_count_by_source(struct ast_channel *chan, const char *source, enum ast_audiohook_type type);
+
+/*!
+ \brief Find out how many spies of a certain type exist on a given channel, and are in state running.
+ \param chan The channel on which to find the spies
+ \param source The source of the audiohook
+ \param type The type of spy to look for
+ \return Return the number of running audiohooks which are from the source specified
+
+ Note: Function performs no locking.
+*/
+int ast_channel_audiohook_count_by_source_running(struct ast_channel *chan, const char *source, enum ast_audiohook_type type);
+
+/*! \brief Lock an audiohook
+ * \param ah Audiohook structure
+ */
+#define ast_audiohook_lock(ah) ast_mutex_lock(&(ah)->lock)
+
+/*! \brief Unlock an audiohook
+ * \param ah Audiohook structure
+ */
+#define ast_audiohook_unlock(ah) ast_mutex_unlock(&(ah)->lock)
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _ASTERISK_AUDIOHOOK_H */
diff --git a/trunk/include/asterisk/autoconfig.h.in b/trunk/include/asterisk/autoconfig.h.in
new file mode 100644
index 000000000..3e9217689
--- /dev/null
+++ b/trunk/include/asterisk/autoconfig.h.in
@@ -0,0 +1,1205 @@
+/* include/asterisk/autoconfig.h.in. Generated from configure.ac by autoheader. */
+
+#ifndef ASTERISK_AUTOCONFIG_H
+#define ASTERISK_AUTOCONFIG_H
+
+#include "asterisk/buildopts.h"
+
+
+
+/* Define to 1 if the `closedir' function returns void instead of `int'. */
+#undef CLOSEDIR_VOID
+
+/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
+ systems. This function is required for `alloca.c' support on those systems.
+ */
+#undef CRAY_STACKSEG_END
+
+/* Define to 1 if using `alloca.c'. */
+#undef C_ALLOCA
+
+/* Define this to indicate the ${ACOS_DESCRIP} library */
+#undef HAVE_ACOS
+
+/* Define this to indicate the ${ACOSL_DESCRIP} library */
+#undef HAVE_ACOSL
+
+/* Define to indicate the ${ACOSL_DESCRIP} library version */
+#undef HAVE_ACOSL_VERSION
+
+/* Define to indicate the ${ACOS_DESCRIP} library version */
+#undef HAVE_ACOS_VERSION
+
+/* Define to 1 if you have the `alarm' function. */
+#undef HAVE_ALARM
+
+/* Define to 1 if you have `alloca', as a function or macro. */
+#undef HAVE_ALLOCA
+
+/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
+ */
+#undef HAVE_ALLOCA_H
+
+/* Define this to indicate the ${ALSA_DESCRIP} library */
+#undef HAVE_ALSA
+
+/* Define to indicate the ${ALSA_DESCRIP} library version */
+#undef HAVE_ALSA_VERSION
+
+/* Define to 1 if you have the <arpa/inet.h> header file. */
+#undef HAVE_ARPA_INET_H
+
+/* Define this to indicate the ${ASIN_DESCRIP} library */
+#undef HAVE_ASIN
+
+/* Define this to indicate the ${ASINL_DESCRIP} library */
+#undef HAVE_ASINL
+
+/* Define to indicate the ${ASINL_DESCRIP} library version */
+#undef HAVE_ASINL_VERSION
+
+/* Define to indicate the ${ASIN_DESCRIP} library version */
+#undef HAVE_ASIN_VERSION
+
+/* Define to 1 if you have the `asprintf' function. */
+#undef HAVE_ASPRINTF
+
+/* Define this to indicate the ${ATAN_DESCRIP} library */
+#undef HAVE_ATAN
+
+/* Define this to indicate the ${ATAN2_DESCRIP} library */
+#undef HAVE_ATAN2
+
+/* Define this to indicate the ${ATAN2L_DESCRIP} library */
+#undef HAVE_ATAN2L
+
+/* Define to indicate the ${ATAN2L_DESCRIP} library version */
+#undef HAVE_ATAN2L_VERSION
+
+/* Define to indicate the ${ATAN2_DESCRIP} library version */
+#undef HAVE_ATAN2_VERSION
+
+/* Define this to indicate the ${ATANL_DESCRIP} library */
+#undef HAVE_ATANL
+
+/* Define to indicate the ${ATANL_DESCRIP} library version */
+#undef HAVE_ATANL_VERSION
+
+/* Define to indicate the ${ATAN_DESCRIP} library version */
+#undef HAVE_ATAN_VERSION
+
+/* Define to 1 if you have the `atexit' function. */
+#undef HAVE_ATEXIT
+
+/* Define to 1 if your GCC C compiler supports the 'always_inline' attribute.
+ */
+#undef HAVE_ATTRIBUTE_always_inline
+
+/* Define to 1 if your GCC C compiler supports the 'const' attribute. */
+#undef HAVE_ATTRIBUTE_const
+
+/* Define to 1 if your GCC C compiler supports the 'deprecated' attribute. */
+#undef HAVE_ATTRIBUTE_deprecated
+
+/* Define to 1 if your GCC C compiler supports the 'malloc' attribute. */
+#undef HAVE_ATTRIBUTE_malloc
+
+/* Define to 1 if your GCC C compiler supports the 'pure' attribute. */
+#undef HAVE_ATTRIBUTE_pure
+
+/* Define to 1 if your GCC C compiler supports the 'unused' attribute. */
+#undef HAVE_ATTRIBUTE_unused
+
+/* Define this to indicate the ${BKTR_DESCRIP} library */
+#undef HAVE_BKTR
+
+/* Define to indicate the ${BKTR_DESCRIP} library version */
+#undef HAVE_BKTR_VERSION
+
+/* Define to 1 if byteswap.h macros are available. */
+#undef HAVE_BYTESWAP_H
+
+/* Define to 1 if you have the `bzero' function. */
+#undef HAVE_BZERO
+
+/* Define this to indicate the ${CAP_DESCRIP} library */
+#undef HAVE_CAP
+
+/* Define to indicate the ${CAP_DESCRIP} library version */
+#undef HAVE_CAP_VERSION
+
+/* Define this to indicate the ${CEIL_DESCRIP} library */
+#undef HAVE_CEIL
+
+/* Define this to indicate the ${CEILL_DESCRIP} library */
+#undef HAVE_CEILL
+
+/* Define to indicate the ${CEILL_DESCRIP} library version */
+#undef HAVE_CEILL_VERSION
+
+/* Define to indicate the ${CEIL_DESCRIP} library version */
+#undef HAVE_CEIL_VERSION
+
+/* Define to 1 if your system has a working `chown' function. */
+#undef HAVE_CHOWN
+
+/* Define this to indicate the ${COS_DESCRIP} library */
+#undef HAVE_COS
+
+/* Define this to indicate the ${COSL_DESCRIP} library */
+#undef HAVE_COSL
+
+/* Define to indicate the ${COSL_DESCRIP} library version */
+#undef HAVE_COSL_VERSION
+
+/* Define to indicate the ${COS_DESCRIP} library version */
+#undef HAVE_COS_VERSION
+
+/* Define this to indicate the ${CRYPTO_DESCRIP} library */
+#undef HAVE_CRYPTO
+
+/* Define to indicate the ${CRYPTO_DESCRIP} library version */
+#undef HAVE_CRYPTO_VERSION
+
+/* Define if your system has the curl libraries. */
+#undef HAVE_CURL
+
+/* Define this to indicate the ${CURSES_DESCRIP} library */
+#undef HAVE_CURSES
+
+/* Define to indicate the ${CURSES_DESCRIP} library version */
+#undef HAVE_CURSES_VERSION
+
+/* Define to 1 if your system has /dev/urandom. */
+#undef HAVE_DEV_URANDOM
+
+/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
+ */
+#undef HAVE_DIRENT_H
+
+/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
+#undef HAVE_DOPRNT
+
+/* Define to 1 if you have the `dup2' function. */
+#undef HAVE_DUP2
+
+/* Define to 1 if you have the `endpwent' function. */
+#undef HAVE_ENDPWENT
+
+/* Define to 1 if your system has working epoll support. */
+#undef HAVE_EPOLL
+
+/* Define this to indicate the ${EXP_DESCRIP} library */
+#undef HAVE_EXP
+
+/* Define this to indicate the ${EXP10_DESCRIP} library */
+#undef HAVE_EXP10
+
+/* Define this to indicate the ${EXP10L_DESCRIP} library */
+#undef HAVE_EXP10L
+
+/* Define to indicate the ${EXP10L_DESCRIP} library version */
+#undef HAVE_EXP10L_VERSION
+
+/* Define to indicate the ${EXP10_DESCRIP} library version */
+#undef HAVE_EXP10_VERSION
+
+/* Define this to indicate the ${EXP2_DESCRIP} library */
+#undef HAVE_EXP2
+
+/* Define this to indicate the ${EXP2L_DESCRIP} library */
+#undef HAVE_EXP2L
+
+/* Define to indicate the ${EXP2L_DESCRIP} library version */
+#undef HAVE_EXP2L_VERSION
+
+/* Define to indicate the ${EXP2_DESCRIP} library version */
+#undef HAVE_EXP2_VERSION
+
+/* Define this to indicate the ${EXPL_DESCRIP} library */
+#undef HAVE_EXPL
+
+/* Define to indicate the ${EXPL_DESCRIP} library version */
+#undef HAVE_EXPL_VERSION
+
+/* Define to indicate the ${EXP_DESCRIP} library version */
+#undef HAVE_EXP_VERSION
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#undef HAVE_FCNTL_H
+
+/* Define this to indicate the ${FFMPEG_DESCRIP} library */
+#undef HAVE_FFMPEG
+
+/* Define to indicate the ${FFMPEG_DESCRIP} library version */
+#undef HAVE_FFMPEG_VERSION
+
+/* Define this to indicate the ${FLOOR_DESCRIP} library */
+#undef HAVE_FLOOR
+
+/* Define this to indicate the ${FLOORL_DESCRIP} library */
+#undef HAVE_FLOORL
+
+/* Define to indicate the ${FLOORL_DESCRIP} library version */
+#undef HAVE_FLOORL_VERSION
+
+/* Define to indicate the ${FLOOR_DESCRIP} library version */
+#undef HAVE_FLOOR_VERSION
+
+/* Define this to indicate the ${FMOD_DESCRIP} library */
+#undef HAVE_FMOD
+
+/* Define this to indicate the ${FMODL_DESCRIP} library */
+#undef HAVE_FMODL
+
+/* Define to indicate the ${FMODL_DESCRIP} library version */
+#undef HAVE_FMODL_VERSION
+
+/* Define to indicate the ${FMOD_DESCRIP} library version */
+#undef HAVE_FMOD_VERSION
+
+/* Define to 1 if you have the `fopencookie' function. */
+#undef HAVE_FOPENCOOKIE
+
+/* Define to 1 if you have the `fork' function. */
+#undef HAVE_FORK
+
+/* Define this to indicate the ${FREETDS_DESCRIP} library */
+#undef HAVE_FREETDS
+
+/* Define to indicate the ${FREETDS_DESCRIP} library version */
+#undef HAVE_FREETDS_VERSION
+
+/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */
+#undef HAVE_FSEEKO
+
+/* Define to 1 if you have the `ftruncate' function. */
+#undef HAVE_FTRUNCATE
+
+/* Define to 1 if you have the `funopen' function. */
+#undef HAVE_FUNOPEN
+
+/* Define to 1 if your GCC C compiler provides atomic operations. */
+#undef HAVE_GCC_ATOMICS
+
+/* Define to 1 if you have the `getcwd' function. */
+#undef HAVE_GETCWD
+
+/* Define to 1 if you have the `gethostbyname' function. */
+#undef HAVE_GETHOSTBYNAME
+
+/* Define to 1 if your system has gethostbyname_r with 5 arguments. */
+#undef HAVE_GETHOSTBYNAME_R_5
+
+/* Define to 1 if your system has gethostbyname_r with 6 arguments. */
+#undef HAVE_GETHOSTBYNAME_R_6
+
+/* Define to 1 if you have the `gethostname' function. */
+#undef HAVE_GETHOSTNAME
+
+/* Define to 1 if you have the `getloadavg' function. */
+#undef HAVE_GETLOADAVG
+
+/* Define to 1 if you have the `getpagesize' function. */
+#undef HAVE_GETPAGESIZE
+
+/* Define to 1 if you have the `gettimeofday' function. */
+#undef HAVE_GETTIMEOFDAY
+
+/* Define to 1 if you have the `glob' function. */
+#undef HAVE_GLOB
+
+/* Define to indicate the GSM library */
+#undef HAVE_GSM
+
+/* Define to indicate that gsm.h is in gsm/gsm.h */
+#undef HAVE_GSM_GSM_HEADER
+
+/* Define to indicate that gsm.h has no prefix for its location */
+#undef HAVE_GSM_HEADER
+
+/* Define if your system has the GTK libraries. */
+#undef HAVE_GTK
+
+/* Define if your system has the GTK2 libraries. */
+#undef HAVE_GTK2
+
+/* Define this to indicate the ${ICONV_DESCRIP} library */
+#undef HAVE_ICONV
+
+/* Define to indicate the ${ICONV_DESCRIP} library version */
+#undef HAVE_ICONV_VERSION
+
+/* Define this to indicate the ${IKSEMEL_DESCRIP} library */
+#undef HAVE_IKSEMEL
+
+/* Define to indicate the ${IKSEMEL_DESCRIP} library version */
+#undef HAVE_IKSEMEL_VERSION
+
+/* Define if your system has the UW IMAP Toolkit c-client library. */
+#undef HAVE_IMAP_TK
+
+/* Define if your system has the UW IMAP Toolkit c-client library version 2006
+ or greater. */
+#undef HAVE_IMAP_TK2006
+
+/* Define to 1 if you have the `inet_aton' function. */
+#undef HAVE_INET_ATON
+
+/* Define to 1 if you have the `inet_ntoa' function. */
+#undef HAVE_INET_NTOA
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define if your system has the IP_MTU_DISCOVER headers. */
+#undef HAVE_IP_MTU_DISCOVER
+
+/* Define IP_MTU_DISCOVER headers version */
+#undef HAVE_IP_MTU_DISCOVER_VERSION
+
+/* Define to 1 if you have the `isascii' function. */
+#undef HAVE_ISASCII
+
+/* Define this to indicate the ${ISDNNET_DESCRIP} library */
+#undef HAVE_ISDNNET
+
+/* Define to indicate the ${ISDNNET_DESCRIP} library version */
+#undef HAVE_ISDNNET_VERSION
+
+/* Define this to indicate the ${JACK_DESCRIP} library */
+#undef HAVE_JACK
+
+/* Define to indicate the ${JACK_DESCRIP} library version */
+#undef HAVE_JACK_VERSION
+
+/* Define to 1 if you have the <libintl.h> header file. */
+#undef HAVE_LIBINTL_H
+
+/* Define to 1 if you have the <limits.h> header file. */
+#undef HAVE_LIMITS_H
+
+/* Define to 1 if your system has linux/compiler.h. */
+#undef HAVE_LINUX_COMPILER_H
+
+/* Define to 1 if you have the <locale.h> header file. */
+#undef HAVE_LOCALE_H
+
+/* Define to 1 if you have the `localtime_r' function. */
+#undef HAVE_LOCALTIME_R
+
+/* Define this to indicate the ${LOG_DESCRIP} library */
+#undef HAVE_LOG
+
+/* Define this to indicate the ${LOG10_DESCRIP} library */
+#undef HAVE_LOG10
+
+/* Define this to indicate the ${LOG10L_DESCRIP} library */
+#undef HAVE_LOG10L
+
+/* Define to indicate the ${LOG10L_DESCRIP} library version */
+#undef HAVE_LOG10L_VERSION
+
+/* Define to indicate the ${LOG10_DESCRIP} library version */
+#undef HAVE_LOG10_VERSION
+
+/* Define this to indicate the ${LOG2_DESCRIP} library */
+#undef HAVE_LOG2
+
+/* Define this to indicate the ${LOG2L_DESCRIP} library */
+#undef HAVE_LOG2L
+
+/* Define to indicate the ${LOG2L_DESCRIP} library version */
+#undef HAVE_LOG2L_VERSION
+
+/* Define to indicate the ${LOG2_DESCRIP} library version */
+#undef HAVE_LOG2_VERSION
+
+/* Define this to indicate the ${LOGL_DESCRIP} library */
+#undef HAVE_LOGL
+
+/* Define to indicate the ${LOGL_DESCRIP} library version */
+#undef HAVE_LOGL_VERSION
+
+/* Define to indicate the ${LOG_DESCRIP} library version */
+#undef HAVE_LOG_VERSION
+
+/* Define this to indicate the ${LTDL_DESCRIP} library */
+#undef HAVE_LTDL
+
+/* Define to indicate the ${LTDL_DESCRIP} library version */
+#undef HAVE_LTDL_VERSION
+
+/* Define this to indicate the ${LUA_DESCRIP} library */
+#undef HAVE_LUA
+
+/* Define to indicate the ${LUA_DESCRIP} library version */
+#undef HAVE_LUA_VERSION
+
+/* Define to 1 if you have the <malloc.h> header file. */
+#undef HAVE_MALLOC_H
+
+/* Define to 1 if you have the `memchr' function. */
+#undef HAVE_MEMCHR
+
+/* Define to 1 if you have the `memmove' function. */
+#undef HAVE_MEMMOVE
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the `memset' function. */
+#undef HAVE_MEMSET
+
+/* Define this to indicate the ${MISDN_DESCRIP} library */
+#undef HAVE_MISDN
+
+/* Define if your system has the MISDN_FAC_ERROR headers. */
+#undef HAVE_MISDN_FAC_ERROR
+
+/* Define MISDN_FAC_ERROR headers version */
+#undef HAVE_MISDN_FAC_ERROR_VERSION
+
+/* Define if your system has the MISDN_FAC_RESULT headers. */
+#undef HAVE_MISDN_FAC_RESULT
+
+/* Define MISDN_FAC_RESULT headers version */
+#undef HAVE_MISDN_FAC_RESULT_VERSION
+
+/* Define to indicate the ${MISDN_DESCRIP} library version */
+#undef HAVE_MISDN_VERSION
+
+/* Define to 1 if you have the `mkdir' function. */
+#undef HAVE_MKDIR
+
+/* Define to 1 if you have a working `mmap' system call. */
+#undef HAVE_MMAP
+
+/* Define to 1 if you have the `munmap' function. */
+#undef HAVE_MUNMAP
+
+/* Define this to indicate the ${NBS_DESCRIP} library */
+#undef HAVE_NBS
+
+/* Define to indicate the ${NBS_DESCRIP} library version */
+#undef HAVE_NBS_VERSION
+
+/* Define this to indicate the ${NCURSES_DESCRIP} library */
+#undef HAVE_NCURSES
+
+/* Define to indicate the ${NCURSES_DESCRIP} library version */
+#undef HAVE_NCURSES_VERSION
+
+/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
+#undef HAVE_NDIR_H
+
+/* Define to 1 if you have the <netdb.h> header file. */
+#undef HAVE_NETDB_H
+
+/* Define to 1 if you have the <netinet/in.h> header file. */
+#undef HAVE_NETINET_IN_H
+
+/* Define if your system has the NETSNMP libraries. */
+#undef HAVE_NETSNMP
+
+/* Define this to indicate the ${NEWT_DESCRIP} library */
+#undef HAVE_NEWT
+
+/* Define to indicate the ${NEWT_DESCRIP} library version */
+#undef HAVE_NEWT_VERSION
+
+/* Define this to indicate the ${OGG_DESCRIP} library */
+#undef HAVE_OGG
+
+/* Define to indicate the ${OGG_DESCRIP} library version */
+#undef HAVE_OGG_VERSION
+
+/* Define if your system has the OpenH323 libraries. */
+#undef HAVE_OPENH323
+
+/* Define this to indicate the ${OPENSSL_DESCRIP} library */
+#undef HAVE_OPENSSL
+
+/* Define to indicate the ${OPENSSL_DESCRIP} library version */
+#undef HAVE_OPENSSL_VERSION
+
+/* Define this to indicate the ${OSPTK_DESCRIP} library */
+#undef HAVE_OSPTK
+
+/* Define to indicate the ${OSPTK_DESCRIP} library version */
+#undef HAVE_OSPTK_VERSION
+
+/* Define this to indicate the ${OSS_DESCRIP} library */
+#undef HAVE_OSS
+
+/* Define to indicate the ${OSS_DESCRIP} library version */
+#undef HAVE_OSS_VERSION
+
+/* Define to 1 if OSX atomic operations are supported. */
+#undef HAVE_OSX_ATOMICS
+
+/* Define to indicate the PostgreSQL library */
+#undef HAVE_PGSQL
+
+/* Define to 1 if your system defines IP_PKTINFO. */
+#undef HAVE_PKTINFO
+
+/* Define this to indicate the ${POPT_DESCRIP} library */
+#undef HAVE_POPT
+
+/* Define to indicate the ${POPT_DESCRIP} library version */
+#undef HAVE_POPT_VERSION
+
+/* Define this to indicate the ${PORTAUDIO_DESCRIP} library */
+#undef HAVE_PORTAUDIO
+
+/* Define to indicate the ${PORTAUDIO_DESCRIP} library version */
+#undef HAVE_PORTAUDIO_VERSION
+
+/* Define this to indicate the ${POW_DESCRIP} library */
+#undef HAVE_POW
+
+/* Define this to indicate the ${POWL_DESCRIP} library */
+#undef HAVE_POWL
+
+/* Define to indicate the ${POWL_DESCRIP} library version */
+#undef HAVE_POWL_VERSION
+
+/* Define to indicate the ${POW_DESCRIP} library version */
+#undef HAVE_POW_VERSION
+
+/* Define this to indicate the ${PRI_DESCRIP} library */
+#undef HAVE_PRI
+
+/* Define to indicate the ${PRI_DESCRIP} library version */
+#undef HAVE_PRI_VERSION
+
+/* Define if you have POSIX threads libraries and header files. */
+#undef HAVE_PTHREAD
+
+/* Define to 1 if your system defines PTHREAD_MUTEX_RECURSIVE_NP in pthread.h
+ */
+#undef HAVE_PTHREAD_MUTEX_RECURSIVE_NP
+
+/* Define if your system has the PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
+ headers. */
+#undef HAVE_PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
+
+/* Define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP headers version */
+#undef HAVE_PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP_VERSION
+
+/* Define if your system has the PTHREAD_RWLOCK_INITIALIZER headers. */
+#undef HAVE_PTHREAD_RWLOCK_INITIALIZER
+
+/* Define PTHREAD_RWLOCK_INITIALIZER headers version */
+#undef HAVE_PTHREAD_RWLOCK_INITIALIZER_VERSION
+
+/* Define to 1 if your system defines PTHREAD_RWLOCK_PREFER_WRITER_NP in
+ pthread.h */
+#undef HAVE_PTHREAD_RWLOCK_PREFER_WRITER_NP
+
+/* Define to 1 if the system has the type `ptrdiff_t'. */
+#undef HAVE_PTRDIFF_T
+
+/* Define to 1 if you have the `putenv' function. */
+#undef HAVE_PUTENV
+
+/* Define if your system has the PWLib libraries. */
+#undef HAVE_PWLIB
+
+/* Define this to indicate the ${RADIUS_DESCRIP} library */
+#undef HAVE_RADIUS
+
+/* Define to indicate the ${RADIUS_DESCRIP} library version */
+#undef HAVE_RADIUS_VERSION
+
+/* Define to 1 if you have the `regcomp' function. */
+#undef HAVE_REGCOMP
+
+/* Define this to indicate the ${REMAINDER_DESCRIP} library */
+#undef HAVE_REMAINDER
+
+/* Define this to indicate the ${REMAINDERL_DESCRIP} library */
+#undef HAVE_REMAINDERL
+
+/* Define to indicate the ${REMAINDERL_DESCRIP} library version */
+#undef HAVE_REMAINDERL_VERSION
+
+/* Define to indicate the ${REMAINDER_DESCRIP} library version */
+#undef HAVE_REMAINDER_VERSION
+
+/* Define to 1 if your system has the ndestroy resolver function. */
+#undef HAVE_RES_NDESTROY
+
+/* Define to 1 if your system has the re-entrant resolver functions. */
+#undef HAVE_RES_NINIT
+
+/* Define to 1 if you have the `re_comp' function. */
+#undef HAVE_RE_COMP
+
+/* Define this to indicate the ${RINT_DESCRIP} library */
+#undef HAVE_RINT
+
+/* Define this to indicate the ${RINTL_DESCRIP} library */
+#undef HAVE_RINTL
+
+/* Define to indicate the ${RINTL_DESCRIP} library version */
+#undef HAVE_RINTL_VERSION
+
+/* Define to indicate the ${RINT_DESCRIP} library version */
+#undef HAVE_RINT_VERSION
+
+/* Define this to indicate the ${ROUND_DESCRIP} library */
+#undef HAVE_ROUND
+
+/* Define this to indicate the ${ROUNDL_DESCRIP} library */
+#undef HAVE_ROUNDL
+
+/* Define to indicate the ${ROUNDL_DESCRIP} library version */
+#undef HAVE_ROUNDL_VERSION
+
+/* Define to indicate the ${ROUND_DESCRIP} library version */
+#undef HAVE_ROUND_VERSION
+
+/* Define if your system has the RTLD_NOLOAD headers. */
+#undef HAVE_RTLD_NOLOAD
+
+/* Define RTLD_NOLOAD headers version */
+#undef HAVE_RTLD_NOLOAD_VERSION
+
+/* Define if your system has the SDL libraries. */
+#undef HAVE_SDL
+
+/* Define this to indicate the ${SDL_IMAGE_DESCRIP} library */
+#undef HAVE_SDL_IMAGE
+
+/* Define to indicate the ${SDL_IMAGE_DESCRIP} library version */
+#undef HAVE_SDL_IMAGE_VERSION
+
+/* Define to 1 if you have the `select' function. */
+#undef HAVE_SELECT
+
+/* Define to 1 if you have the `setenv' function. */
+#undef HAVE_SETENV
+
+/* Define this to indicate the ${SIN_DESCRIP} library */
+#undef HAVE_SIN
+
+/* Define this to indicate the ${SINL_DESCRIP} library */
+#undef HAVE_SINL
+
+/* Define to indicate the ${SINL_DESCRIP} library version */
+#undef HAVE_SINL_VERSION
+
+/* Define to indicate the ${SIN_DESCRIP} library version */
+#undef HAVE_SIN_VERSION
+
+/* Define to 1 if you have the `socket' function. */
+#undef HAVE_SOCKET
+
+/* Define to 1 if your system has soxmix application. */
+#undef HAVE_SOXMIX
+
+/* Define this to indicate the ${SPEEX_DESCRIP} library */
+#undef HAVE_SPEEX
+
+/* Define this to indicate the ${SPEEXDSP_DESCRIP} library */
+#undef HAVE_SPEEXDSP
+
+/* Define to indicate the ${SPEEXDSP_DESCRIP} library version */
+#undef HAVE_SPEEXDSP_VERSION
+
+/* Define to indicate the ${SPEEX_DESCRIP} library version */
+#undef HAVE_SPEEX_VERSION
+
+/* Define this to indicate the ${SQLITE_DESCRIP} library */
+#undef HAVE_SQLITE
+
+/* Define this to indicate the ${SQLITE3_DESCRIP} library */
+#undef HAVE_SQLITE3
+
+/* Define to indicate the ${SQLITE3_DESCRIP} library version */
+#undef HAVE_SQLITE3_VERSION
+
+/* Define to indicate the ${SQLITE_DESCRIP} library version */
+#undef HAVE_SQLITE_VERSION
+
+/* Define this to indicate the ${SQRT_DESCRIP} library */
+#undef HAVE_SQRT
+
+/* Define this to indicate the ${SQRTL_DESCRIP} library */
+#undef HAVE_SQRTL
+
+/* Define to indicate the ${SQRTL_DESCRIP} library version */
+#undef HAVE_SQRTL_VERSION
+
+/* Define to indicate the ${SQRT_DESCRIP} library version */
+#undef HAVE_SQRT_VERSION
+
+/* Define this to indicate the ${SS7_DESCRIP} library */
+#undef HAVE_SS7
+
+/* Define to indicate the ${SS7_DESCRIP} library version */
+#undef HAVE_SS7_VERSION
+
+/* Define to 1 if `stat' has the bug that it succeeds when given the
+ zero-length file name argument. */
+#undef HAVE_STAT_EMPTY_STRING_BUG
+
+/* Define to 1 if stdbool.h conforms to C99. */
+#undef HAVE_STDBOOL_H
+
+/* Define to 1 if you have the <stddef.h> header file. */
+#undef HAVE_STDDEF_H
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the `strcasecmp' function. */
+#undef HAVE_STRCASECMP
+
+/* Define to 1 if you have the `strcasestr' function. */
+#undef HAVE_STRCASESTR
+
+/* Define to 1 if you have the `strchr' function. */
+#undef HAVE_STRCHR
+
+/* Define to 1 if you have the `strcoll' function and it is properly defined.
+ */
+#undef HAVE_STRCOLL
+
+/* Define to 1 if you have the `strcspn' function. */
+#undef HAVE_STRCSPN
+
+/* Define to 1 if you have the `strdup' function. */
+#undef HAVE_STRDUP
+
+/* Define to 1 if you have the `strerror' function. */
+#undef HAVE_STRERROR
+
+/* Define to 1 if you have the `strftime' function. */
+#undef HAVE_STRFTIME
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the `strlcat' function. */
+#undef HAVE_STRLCAT
+
+/* Define to 1 if you have the `strlcpy' function. */
+#undef HAVE_STRLCPY
+
+/* Define to 1 if you have the `strncasecmp' function. */
+#undef HAVE_STRNCASECMP
+
+/* Define to 1 if you have the `strndup' function. */
+#undef HAVE_STRNDUP
+
+/* Define to 1 if you have the `strnlen' function. */
+#undef HAVE_STRNLEN
+
+/* Define to 1 if you have the `strrchr' function. */
+#undef HAVE_STRRCHR
+
+/* Define to 1 if you have the `strsep' function. */
+#undef HAVE_STRSEP
+
+/* Define to 1 if you have the `strspn' function. */
+#undef HAVE_STRSPN
+
+/* Define to 1 if you have the `strstr' function. */
+#undef HAVE_STRSTR
+
+/* Define this to indicate the ${STRTOD_DESCRIP} library */
+#undef HAVE_STRTOD
+
+/* Define to indicate the ${STRTOD_DESCRIP} library version */
+#undef HAVE_STRTOD_VERSION
+
+/* Define to 1 if you have the `strtol' function. */
+#undef HAVE_STRTOL
+
+/* Define this to indicate the ${STRTOLD_DESCRIP} library */
+#undef HAVE_STRTOLD
+
+/* Define to indicate the ${STRTOLD_DESCRIP} library version */
+#undef HAVE_STRTOLD_VERSION
+
+/* Define to 1 if you have the `strtoq' function. */
+#undef HAVE_STRTOQ
+
+/* Define to 1 if `st_blksize' is member of `struct stat'. */
+#undef HAVE_STRUCT_STAT_ST_BLKSIZE
+
+/* Define this to indicate the ${SUPPSERV_DESCRIP} library */
+#undef HAVE_SUPPSERV
+
+/* Define to indicate the ${SUPPSERV_DESCRIP} library version */
+#undef HAVE_SUPPSERV_VERSION
+
+/* Define to 1 if your system has sysinfo support */
+#undef HAVE_SYSINFO
+
+/* Define to 1 if you have the <syslog.h> header file. */
+#undef HAVE_SYSLOG_H
+
+/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
+ */
+#undef HAVE_SYS_DIR_H
+
+/* Define to 1 if your sys/endian.h header file provides the bswap16 macro. */
+#undef HAVE_SYS_ENDIAN_BSWAP16
+
+/* Define to 1 if your sys/endian.h header file provides the __swap16 macro.
+ */
+#undef HAVE_SYS_ENDIAN_SWAP16
+
+/* Define to 1 if you have the <sys/file.h> header file. */
+#undef HAVE_SYS_FILE_H
+
+/* Define to 1 if you have the <sys/ioctl.h> header file. */
+#undef HAVE_SYS_IOCTL_H
+
+/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
+ */
+#undef HAVE_SYS_NDIR_H
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+#undef HAVE_SYS_PARAM_H
+
+/* Define to 1 if your system has working sys/poll.h */
+#undef HAVE_SYS_POLL_H
+
+/* Define to 1 if you have the <sys/select.h> header file. */
+#undef HAVE_SYS_SELECT_H
+
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#undef HAVE_SYS_SOCKET_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#undef HAVE_SYS_TIME_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
+#undef HAVE_SYS_WAIT_H
+
+/* Define this to indicate the ${TAN_DESCRIP} library */
+#undef HAVE_TAN
+
+/* Define this to indicate the ${TANL_DESCRIP} library */
+#undef HAVE_TANL
+
+/* Define to indicate the ${TANL_DESCRIP} library version */
+#undef HAVE_TANL_VERSION
+
+/* Define to indicate the ${TAN_DESCRIP} library version */
+#undef HAVE_TAN_VERSION
+
+/* Define this to indicate the ${TERMCAP_DESCRIP} library */
+#undef HAVE_TERMCAP
+
+/* Define to indicate the ${TERMCAP_DESCRIP} library version */
+#undef HAVE_TERMCAP_VERSION
+
+/* Define to 1 if you have the <termios.h> header file. */
+#undef HAVE_TERMIOS_H
+
+/* Define to 1 if your system defines timersub. */
+#undef HAVE_TIMERSUB
+
+/* Define this to indicate the ${TINFO_DESCRIP} library */
+#undef HAVE_TINFO
+
+/* Define to indicate the ${TINFO_DESCRIP} library version */
+#undef HAVE_TINFO_VERSION
+
+/* Define this to indicate the ${TONEZONE_DESCRIP} library */
+#undef HAVE_TONEZONE
+
+/* Define to indicate the ${TONEZONE_DESCRIP} library version */
+#undef HAVE_TONEZONE_VERSION
+
+/* Define this to indicate the ${TRUNC_DESCRIP} library */
+#undef HAVE_TRUNC
+
+/* Define this to indicate the ${TRUNCL_DESCRIP} library */
+#undef HAVE_TRUNCL
+
+/* Define to indicate the ${TRUNCL_DESCRIP} library version */
+#undef HAVE_TRUNCL_VERSION
+
+/* Define to indicate the ${TRUNC_DESCRIP} library version */
+#undef HAVE_TRUNC_VERSION
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define this to indicate the ${UNIXODBC_DESCRIP} library */
+#undef HAVE_UNIXODBC
+
+/* Define to indicate the ${UNIXODBC_DESCRIP} library version */
+#undef HAVE_UNIXODBC_VERSION
+
+/* Define to 1 if you have the `unsetenv' function. */
+#undef HAVE_UNSETENV
+
+/* Define this to indicate the ${USB_DESCRIP} library */
+#undef HAVE_USB
+
+/* Define to indicate the ${USB_DESCRIP} library version */
+#undef HAVE_USB_VERSION
+
+/* Define to 1 if you have the `utime' function. */
+#undef HAVE_UTIME
+
+/* Define to 1 if you have the <utime.h> header file. */
+#undef HAVE_UTIME_H
+
+/* Define to 1 if `utime(file, NULL)' sets file's timestamp to the present. */
+#undef HAVE_UTIME_NULL
+
+/* Define to 1 if you have the `vasprintf' function. */
+#undef HAVE_VASPRINTF
+
+/* Define to 1 if you have the `vfork' function. */
+#undef HAVE_VFORK
+
+/* Define to 1 if you have the <vfork.h> header file. */
+#undef HAVE_VFORK_H
+
+/* Define to 1 if your system has linux/videodev.h. */
+#undef HAVE_VIDEODEV_H
+
+/* Define this to indicate the ${VORBIS_DESCRIP} library */
+#undef HAVE_VORBIS
+
+/* Define to indicate the ${VORBIS_DESCRIP} library version */
+#undef HAVE_VORBIS_VERSION
+
+/* Define if your system has the VoiceTronix API libraries. */
+#undef HAVE_VPB
+
+/* Define to 1 if you have the `vprintf' function. */
+#undef HAVE_VPRINTF
+
+/* Define to 1 if you have the <winsock2.h> header file. */
+#undef HAVE_WINSOCK2_H
+
+/* Define to 1 if you have the <winsock.h> header file. */
+#undef HAVE_WINSOCK_H
+
+/* Define to 1 if `fork' works. */
+#undef HAVE_WORKING_FORK
+
+/* Define to 1 if `vfork' works. */
+#undef HAVE_WORKING_VFORK
+
+/* Define this to indicate the ${X11_DESCRIP} library */
+#undef HAVE_X11
+
+/* Define to indicate the ${X11_DESCRIP} library version */
+#undef HAVE_X11_VERSION
+
+/* Define this to indicate the ${ZAPTEL_DESCRIP} library */
+#undef HAVE_ZAPTEL
+
+/* Define if your system has the ZAPTEL_CHANALARMS headers. */
+#undef HAVE_ZAPTEL_CHANALARMS
+
+/* Define ZAPTEL_CHANALARMS headers version */
+#undef HAVE_ZAPTEL_CHANALARMS_VERSION
+
+/* Define if your system has the ZAPTEL_ECHOCANPARAMS headers. */
+#undef HAVE_ZAPTEL_ECHOCANPARAMS
+
+/* Define ZAPTEL_ECHOCANPARAMS headers version */
+#undef HAVE_ZAPTEL_ECHOCANPARAMS_VERSION
+
+/* Define if your system has the ZAPTEL_HWGAIN headers. */
+#undef HAVE_ZAPTEL_HWGAIN
+
+/* Define ZAPTEL_HWGAIN headers version */
+#undef HAVE_ZAPTEL_HWGAIN_VERSION
+
+/* Define if your system has the ZAPTEL_TRANSCODE headers. */
+#undef HAVE_ZAPTEL_TRANSCODE
+
+/* Define ZAPTEL_TRANSCODE headers version */
+#undef HAVE_ZAPTEL_TRANSCODE_VERSION
+
+/* Define to indicate the ${ZAPTEL_DESCRIP} library version */
+#undef HAVE_ZAPTEL_VERSION
+
+/* Define this to indicate the ${ZAPTEL_VLDTMF_DESCRIP} library */
+#undef HAVE_ZAPTEL_VLDTMF
+
+/* Define to indicate the ${ZAPTEL_VLDTMF_DESCRIP} library version */
+#undef HAVE_ZAPTEL_VLDTMF_VERSION
+
+/* Define this to indicate the ${ZLIB_DESCRIP} library */
+#undef HAVE_ZLIB
+
+/* Define to indicate the ${ZLIB_DESCRIP} library version */
+#undef HAVE_ZLIB_VERSION
+
+/* Define to 1 if the system has the type `_Bool'. */
+#undef HAVE__BOOL
+
+/* Define to 1 if `lstat' dereferences a symlink specified with a trailing
+ slash. */
+#undef LSTAT_FOLLOWS_SLASHED_SYMLINK
+
+/* Build chan_misdn for mISDN 1.2 or later. */
+#undef MISDN_1_2
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define to 1 if the C compiler supports function prototypes. */
+#undef PROTOTYPES
+
+/* Define to necessary symbol if this constant uses a non-standard name on
+ your system. */
+#undef PTHREAD_CREATE_JOINABLE
+
+/* Define as the return type of signal handlers (`int' or `void'). */
+#undef RETSIGTYPE
+
+/* Define to the type of arg 1 for `select'. */
+#undef SELECT_TYPE_ARG1
+
+/* Define to the type of args 2, 3 and 4 for `select'. */
+#undef SELECT_TYPE_ARG234
+
+/* Define to the type of arg 5 for `select'. */
+#undef SELECT_TYPE_ARG5
+
+/* Define to 1 if the `setvbuf' function takes the buffering type as its
+ second argument and the buffer pointer as the third, as on System V before
+ release 3. */
+#undef SETVBUF_REVERSED
+
+/* The size of `int', as computed by sizeof. */
+#undef SIZEOF_INT
+
+/* If using the C implementation of alloca, define if you know the
+ direction of stack growth for your system; otherwise it will be
+ automatically deduced at runtime.
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown */
+#undef STACK_DIRECTION
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+#undef TIME_WITH_SYS_TIME
+
+/* Define to 1 if your <sys/time.h> declares `struct tm'. */
+#undef TM_IN_SYS_TIME
+
+/* Define to 1 if on AIX 3.
+ System headers sometimes define this.
+ We just want to avoid a redefinition error message. */
+#ifndef _ALL_SOURCE
+# undef _ALL_SOURCE
+#endif
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+#undef _FILE_OFFSET_BITS
+
+/* Enable GNU extensions on systems that have them. */
+#ifndef _GNU_SOURCE
+# undef _GNU_SOURCE
+#endif
+
+/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */
+#undef _LARGEFILE_SOURCE
+
+/* Define for large files, on AIX-style hosts. */
+#undef _LARGE_FILES
+
+/* Define to 1 if on MINIX. */
+#undef _MINIX
+
+/* Define to 2 if the system does not provide POSIX.1 features except with
+ this defined. */
+#undef _POSIX_1_SOURCE
+
+/* Define to 1 if you need to in order for `stat' and other things to work. */
+#undef _POSIX_SOURCE
+
+/* Enable extensions on Solaris. */
+#ifndef __EXTENSIONS__
+# undef __EXTENSIONS__
+#endif
+#ifndef _POSIX_PTHREAD_SEMANTICS
+# undef _POSIX_PTHREAD_SEMANTICS
+#endif
+#ifndef _TANDEM_SOURCE
+# undef _TANDEM_SOURCE
+#endif
+
+/* Define like PROTOTYPES; this can be used by system headers. */
+#undef __PROTOTYPES
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+#undef gid_t
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+ calls it, or to nothing if 'inline' is not supported under any name. */
+#ifndef __cplusplus
+#undef inline
+#endif
+
+/* Define to `int' if <sys/types.h> does not define. */
+#undef mode_t
+
+/* Define to `long int' if <sys/types.h> does not define. */
+#undef off_t
+
+/* Define to `int' if <sys/types.h> does not define. */
+#undef pid_t
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+#undef size_t
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+#undef uid_t
+
+/* Define as `fork' if `vfork' does not work. */
+#undef vfork
+
+/* Define to empty if the keyword `volatile' does not work. Warning: valid
+ code using `volatile' can become incorrect without. Disable with care. */
+#undef volatile
+
+#endif
+
diff --git a/trunk/include/asterisk/callerid.h b/trunk/include/asterisk/callerid.h
new file mode 100644
index 000000000..8bf27158b
--- /dev/null
+++ b/trunk/include/asterisk/callerid.h
@@ -0,0 +1,345 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2005, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief CallerID (and other GR30) management and generation
+ * Includes code and algorithms from the Zapata library.
+ *
+ * \ref CID
+ *
+ */
+
+/*!
+ * \page CID Caller ID names and numbers
+ *
+ * Caller ID names are currently 8 bit characters, propably
+ * ISO8859-1, depending on what your channel drivers handle.
+ *
+ * IAX2 and SIP caller ID names are UTF8
+ * On ISDN Caller ID names are 7 bit, Almost ASCII
+ * (See http://www.zytrax.com/tech/ia5.html )
+ *
+ * \note Asterisk does not currently support SIP utf8 caller ID names or caller ID's.
+ *
+ * \par See also
+ * \arg \ref callerid.c
+ * \arg \ref callerid.h
+ * \arg \ref Def_CallerPres
+ */
+
+#ifndef _ASTERISK_CALLERID_H
+#define _ASTERISK_CALLERID_H
+
+#define MAX_CALLERID_SIZE 32000
+
+#define CID_PRIVATE_NAME (1 << 0)
+#define CID_PRIVATE_NUMBER (1 << 1)
+#define CID_UNKNOWN_NAME (1 << 2)
+#define CID_UNKNOWN_NUMBER (1 << 3)
+#define CID_MSGWAITING (1 << 4)
+#define CID_NOMSGWAITING (1 << 5)
+
+#define CID_SIG_BELL 1
+#define CID_SIG_V23 2
+#define CID_SIG_DTMF 3
+#define CID_SIG_V23_JP 4
+#define CID_SIG_SMDI 5
+
+#define CID_START_RING 1
+#define CID_START_POLARITY 2
+#define CID_START_POLARITY_IN 3
+
+
+#define AST_LIN2X(a) ((codec == AST_FORMAT_ALAW) ? (AST_LIN2A(a)) : (AST_LIN2MU(a)))
+#define AST_XLAW(a) ((codec == AST_FORMAT_ALAW) ? (AST_ALAW(a)) : (AST_MULAW(a)))
+
+
+struct callerid_state;
+typedef struct callerid_state CIDSTATE;
+
+/*! \brief CallerID Initialization
+ * \par
+ * Initializes the callerid system. Mostly stuff for inverse FFT
+ */
+void callerid_init(void);
+
+/*! \brief Generates a CallerID FSK stream in ulaw format suitable for transmission.
+ * \param buf Buffer to use. If "buf" is supplied, it will use that buffer instead of allocating its own. "buf" must be at least 32000 bytes in size of you want to be sure you don't have an overrun.
+ * \param number Use NULL for no number or "P" for "private"
+ * \param name name to be used
+ * \param flags passed flags
+ * \param callwaiting callwaiting flag
+ * \param codec -- either AST_FORMAT_ULAW or AST_FORMAT_ALAW
+ * This function creates a stream of callerid (a callerid spill) data in ulaw format.
+ * \return It returns the size
+ * (in bytes) of the data (if it returns a size of 0, there is probably an error)
+*/
+int callerid_generate(unsigned char *buf, const char *number, const char *name, int flags, int callwaiting, int codec);
+
+/*! \brief Create a callerID state machine
+ * \param cid_signalling Type of signalling in use
+ *
+ * This function returns a malloc'd instance of the callerid_state data structure.
+ * \return Returns a pointer to a malloc'd callerid_state structure, or NULL on error.
+ */
+struct callerid_state *callerid_new(int cid_signalling);
+
+/*! \brief Read samples into the state machine.
+ * \param cid Which state machine to act upon
+ * \param ubuf containing your samples
+ * \param samples number of samples contained within the buffer.
+ * \param codec which codec (AST_FORMAT_ALAW or AST_FORMAT_ULAW)
+ *
+ * Send received audio to the Caller*ID demodulator.
+ * \return Returns -1 on error, 0 for "needs more samples",
+ * and 1 if the CallerID spill reception is complete.
+ */
+int callerid_feed(struct callerid_state *cid, unsigned char *ubuf, int samples, int codec);
+
+/*! \brief Read samples into the state machine.
+ * \param cid Which state machine to act upon
+ * \param ubuf containing your samples
+ * \param samples number of samples contained within the buffer.
+ * \param codec which codec (AST_FORMAT_ALAW or AST_FORMAT_ULAW)
+ *
+ * Send received audio to the Caller*ID demodulator (for japanese style lines).
+ * \return Returns -1 on error, 0 for "needs more samples",
+ * and 1 if the CallerID spill reception is complete.
+ */
+int callerid_feed_jp(struct callerid_state *cid, unsigned char *ubuf, int samples, int codec);
+
+/*! \brief Extract info out of callerID state machine. Flags are listed above
+ * \param cid Callerid state machine to act upon
+ * \param number Pass the address of a pointer-to-char (will contain the phone number)
+ * \param name Pass the address of a pointer-to-char (will contain the name)
+ * \param flags Pass the address of an int variable(will contain the various callerid flags)
+ *
+ * This function extracts a callerid string out of a callerid_state state machine.
+ * If no number is found, *number will be set to NULL. Likewise for the name.
+ * Flags can contain any of the following:
+ *
+ * \return Returns nothing.
+ */
+void callerid_get(struct callerid_state *cid, char **number, char **name, int *flags);
+
+/*! Get and parse DTMF-based callerid */
+/*!
+ * \param cidstring The actual transmitted string.
+ * \param number The cid number is returned here.
+ * \param flags The cid flags are returned here.
+ * This function parses DTMF callerid.
+ */
+void callerid_get_dtmf(char *cidstring, char *number, int *flags);
+
+/*! \brief Free a callerID state
+ * \param cid This is the callerid_state state machine to free
+ * This function frees callerid_state cid.
+ */
+void callerid_free(struct callerid_state *cid);
+
+/*! \brief Generate Caller-ID spill from the "callerid" field of asterisk (in e-mail address like format)
+ * \param buf buffer for output samples. See callerid_generate() for details regarding buffer.
+ * \param name Caller-ID Name
+ * \param number Caller-ID Number
+ * \param codec Asterisk codec (either AST_FORMAT_ALAW or AST_FORMAT_ULAW)
+ *
+ * Acts like callerid_generate except uses an asterisk format callerid string.
+ */
+int ast_callerid_generate(unsigned char *buf, const char *name, const char *number, int codec);
+
+/*! \brief Generate message waiting indicator (stutter tone) */
+int vmwi_generate(unsigned char *buf, int active, int mdmf, int codec);
+
+/*! \brief Generate Caller-ID spill but in a format suitable for Call Waiting(tm)'s Caller*ID(tm)
+ * See ast_callerid_generate() for other details
+ */
+int ast_callerid_callwaiting_generate(unsigned char *buf, const char *name, const char *number, int codec);
+
+/*! \brief Destructively parse inbuf into name and location (or number)
+ * Parses callerid stream from inbuf and changes into useable form, outputed in name and location.
+ * \param instr buffer of callerid stream (in audio form) to be parsed. Warning, data in buffer is changed.
+ * \param name address of a pointer-to-char for the name value of the stream.
+ * \param location address of a pointer-to-char for the phone number value of the stream.
+ * \return Returns 0 on success, -1 on failure.
+ */
+int ast_callerid_parse(char *instr, char **name, char **location);
+
+/*! Generate a CAS (CPE Alert Signal) tone for 'n' samples */
+/*!
+ * \param outbuf Allocated buffer for data. Must be at least 2400 bytes unless no SAS is desired
+ * \param sas Non-zero if CAS should be preceeded by SAS
+ * \param len How many samples to generate.
+ * \param codec Which codec (AST_FORMAT_ALAW or AST_FORMAT_ULAW)
+ * \return Returns -1 on error (if len is less than 2400), 0 on success.
+ */
+int ast_gen_cas(unsigned char *outbuf, int sas, int len, int codec);
+
+/*! \brief Shrink a phone number in place to just digits (more accurately it just removes ()'s, .'s, and -'s... */
+/*!
+ * \param n The number to be stripped/shrunk
+ * \return Returns nothing important
+ */
+void ast_shrink_phone_number(char *n);
+
+/*! \brief Check if a string consists only of digits and + \#
+ \param n number to be checked.
+ \return Returns 0 if n is a number, 1 if it's not.
+ */
+int ast_isphonenumber(const char *n);
+
+/*! \brief Check if a string consists only of digits and and + \# ( ) - .
+ (meaning it can be cleaned with ast_shrink_phone_number)
+ \param exten The extension (or URI) to be checked.
+ \return Returns 0 if n is a number, 1 if it's not.
+ */
+int ast_is_shrinkable_phonenumber(const char *exten);
+
+int ast_callerid_split(const char *src, char *name, int namelen, char *num, int numlen);
+
+char *ast_callerid_merge(char *buf, int bufsiz, const char *name, const char *num, const char *unknown);
+
+/*
+ * Caller*ID and other GR-30 compatible generation
+ * routines (used by ADSI for example)
+ */
+
+extern float cid_dr[4];
+extern float cid_di[4];
+extern float clidsb;
+
+static inline float callerid_getcarrier(float *cr, float *ci, int bit)
+{
+ /* Move along. There's nothing to see here... */
+ float t;
+ t = *cr * cid_dr[bit] - *ci * cid_di[bit];
+ *ci = *cr * cid_di[bit] + *ci * cid_dr[bit];
+ *cr = t;
+
+ t = 2.0 - (*cr * *cr + *ci * *ci);
+ *cr *= t;
+ *ci *= t;
+ return *cr;
+}
+
+#define PUT_BYTE(a) do { \
+ *(buf++) = (a); \
+ bytes++; \
+} while(0)
+
+#define PUT_AUDIO_SAMPLE(y) do { \
+ int index = (short)(rint(8192.0 * (y))); \
+ *(buf++) = AST_LIN2X(index); \
+ bytes++; \
+} while(0)
+
+#define PUT_CLID_MARKMS do { \
+ int x; \
+ for (x=0;x<8;x++) \
+ PUT_AUDIO_SAMPLE(callerid_getcarrier(&cr, &ci, 1)); \
+} while(0)
+
+#define PUT_CLID_BAUD(bit) do { \
+ while(scont < clidsb) { \
+ PUT_AUDIO_SAMPLE(callerid_getcarrier(&cr, &ci, bit)); \
+ scont += 1.0; \
+ } \
+ scont -= clidsb; \
+} while(0)
+
+
+#define PUT_CLID(byte) do { \
+ int z; \
+ unsigned char b = (byte); \
+ PUT_CLID_BAUD(0); /* Start bit */ \
+ for (z=0;z<8;z++) { \
+ PUT_CLID_BAUD(b & 1); \
+ b >>= 1; \
+ } \
+ PUT_CLID_BAUD(1); /* Stop bit */ \
+} while(0)
+
+/* Various defines and bits for handling PRI- and SS7-type restriction */
+
+#define AST_PRES_NUMBER_TYPE 0x03
+#define AST_PRES_USER_NUMBER_UNSCREENED 0x00
+#define AST_PRES_USER_NUMBER_PASSED_SCREEN 0x01
+#define AST_PRES_USER_NUMBER_FAILED_SCREEN 0x02
+#define AST_PRES_NETWORK_NUMBER 0x03
+
+#define AST_PRES_RESTRICTION 0x60
+#define AST_PRES_ALLOWED 0x00
+#define AST_PRES_RESTRICTED 0x20
+#define AST_PRES_UNAVAILABLE 0x40
+#define AST_PRES_RESERVED 0x60
+
+#define AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED \
+ AST_PRES_USER_NUMBER_UNSCREENED + AST_PRES_ALLOWED
+
+#define AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN \
+ AST_PRES_USER_NUMBER_PASSED_SCREEN + AST_PRES_ALLOWED
+
+#define AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN \
+ AST_PRES_USER_NUMBER_FAILED_SCREEN + AST_PRES_ALLOWED
+
+#define AST_PRES_ALLOWED_NETWORK_NUMBER \
+ AST_PRES_NETWORK_NUMBER + AST_PRES_ALLOWED
+
+#define AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED \
+ AST_PRES_USER_NUMBER_UNSCREENED + AST_PRES_RESTRICTED
+
+#define AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN \
+ AST_PRES_USER_NUMBER_PASSED_SCREEN + AST_PRES_RESTRICTED
+
+#define AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN \
+ AST_PRES_USER_NUMBER_FAILED_SCREEN + AST_PRES_RESTRICTED
+
+#define AST_PRES_PROHIB_NETWORK_NUMBER \
+ AST_PRES_NETWORK_NUMBER + AST_PRES_RESTRICTED
+
+#define AST_PRES_NUMBER_NOT_AVAILABLE \
+ AST_PRES_NETWORK_NUMBER + AST_PRES_UNAVAILABLE
+
+int ast_parse_caller_presentation(const char *data);
+const char *ast_describe_caller_presentation(int data);
+const char *ast_named_caller_presentation(int data);
+
+/*! \page Def_CallerPres Caller ID Presentation
+
+ Caller ID presentation values are used to set properties to a
+ caller ID in PSTN networks, and as RPID value in SIP transactions.
+
+ The following values are available to use:
+ \arg \b Defined value, text string in config file, explanation
+
+ \arg \b AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, "allowed_not_screened", Presentation Allowed, Not Screened,
+ \arg \b AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, "allowed_passed_screen", Presentation Allowed, Passed Screen,
+ \arg \b AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN, "allowed_failed_screen", Presentation Allowed, Failed Screen,
+ \arg \b AST_PRES_ALLOWED_NETWORK_NUMBER, "allowed", Presentation Allowed, Network Number,
+ \arg \b AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED, "prohib_not_screened", Presentation Prohibited, Not Screened,
+ \arg \b AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN, "prohib_passed_screen", Presentation Prohibited, Passed Screen,
+ \arg \b AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN, "prohib_failed_screen", Presentation Prohibited, Failed Screen,
+ \arg \b AST_PRES_PROHIB_NETWORK_NUMBER, "prohib", Presentation Prohibited, Network Number,
+
+ \par References
+ \arg \ref callerid.h Definitions
+ \arg \ref callerid.c Functions
+ \arg \ref CID Caller ID names and numbers
+*/
+
+
+#endif /* _ASTERISK_CALLERID_H */
diff --git a/trunk/include/asterisk/causes.h b/trunk/include/asterisk/causes.h
new file mode 100644
index 000000000..fb4f3c115
--- /dev/null
+++ b/trunk/include/asterisk/causes.h
@@ -0,0 +1,149 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2005, Digium, Inc.
+ *
+ * Martin Pycko <martinp@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief Internal Asterisk hangup causes
+ */
+
+#ifndef _ASTERISK_CAUSES_H
+#define _ASTERISK_CAUSES_H
+
+/*! \page AstCauses Hangup Causes for Asterisk
+
+The Asterisk hangup causes are delivered to the dialplan in the
+${HANGUPCAUSE} channel variable after a call (after execution
+of "dial").
+
+In SIP, we have a conversion table to convert between SIP
+return codes and Q.931 both ways. This is to improve SIP/ISDN
+compatibility.
+
+These are the current codes, based on the Q.931
+specification:
+
+ - AST_CAUSE_UNALLOCATED 1
+ - AST_CAUSE_NO_ROUTE_TRANSIT_NET 2
+ - AST_CAUSE_NO_ROUTE_DESTINATION 3
+ - AST_CAUSE_CHANNEL_UNACCEPTABLE 6
+ - AST_CAUSE_CALL_AWARDED_DELIVERED 7
+ - AST_CAUSE_NORMAL_CLEARING 16
+ - AST_CAUSE_USER_BUSY 17
+ - AST_CAUSE_NO_USER_RESPONSE 18
+ - AST_CAUSE_NO_ANSWER 19
+ - AST_CAUSE_CALL_REJECTED 21
+ - AST_CAUSE_NUMBER_CHANGED 22
+ - AST_CAUSE_DESTINATION_OUT_OF_ORDER 27
+ - AST_CAUSE_INVALID_NUMBER_FORMAT 28
+ - AST_CAUSE_FACILITY_REJECTED 29
+ - AST_CAUSE_RESPONSE_TO_STATUS_ENQUIRY 30
+ - AST_CAUSE_NORMAL_UNSPECIFIED 31
+ - AST_CAUSE_NORMAL_CIRCUIT_CONGESTION 34
+ - AST_CAUSE_NETWORK_OUT_OF_ORDER 38
+ - AST_CAUSE_NORMAL_TEMPORARY_FAILURE 41
+ - AST_CAUSE_SWITCH_CONGESTION 42
+ - AST_CAUSE_ACCESS_INFO_DISCARDED 43
+ - AST_CAUSE_REQUESTED_CHAN_UNAVAIL 44
+ - AST_CAUSE_PRE_EMPTED 45
+ - AST_CAUSE_FACILITY_NOT_SUBSCRIBED 50
+ - AST_CAUSE_OUTGOING_CALL_BARRED 52
+ - AST_CAUSE_INCOMING_CALL_BARRED 54
+ - AST_CAUSE_BEARERCAPABILITY_NOTAUTH 57
+ - AST_CAUSE_BEARERCAPABILITY_NOTAVAIL 58
+ - AST_CAUSE_BEARERCAPABILITY_NOTIMPL 65
+ - AST_CAUSE_CHAN_NOT_IMPLEMENTED 66
+ - AST_CAUSE_FACILITY_NOT_IMPLEMENTED 69
+ - AST_CAUSE_INVALID_CALL_REFERENCE 81
+ - AST_CAUSE_INCOMPATIBLE_DESTINATION 88
+ - AST_CAUSE_INVALID_MSG_UNSPECIFIED 95
+ - AST_CAUSE_MANDATORY_IE_MISSING 96
+ - AST_CAUSE_MESSAGE_TYPE_NONEXIST 97
+ - AST_CAUSE_WRONG_MESSAGE 98
+ - AST_CAUSE_IE_NONEXIST 99
+ - AST_CAUSE_INVALID_IE_CONTENTS 100
+ - AST_CAUSE_WRONG_CALL_STATE 101
+ - AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE 102
+ - AST_CAUSE_MANDATORY_IE_LENGTH_ERROR 103
+ - AST_CAUSE_PROTOCOL_ERROR 111
+ - AST_CAUSE_INTERWORKING 127
+
+For more information:
+- \ref app_dial.c
+*/
+
+/*! \name Causes for disconnection (from Q.931)
+ These are the internal cause codes used in Asterisk.
+ \ref AstCauses
+*/
+/*@{ */
+#define AST_CAUSE_UNALLOCATED 1
+#define AST_CAUSE_NO_ROUTE_TRANSIT_NET 2
+#define AST_CAUSE_NO_ROUTE_DESTINATION 3
+#define AST_CAUSE_CHANNEL_UNACCEPTABLE 6
+#define AST_CAUSE_CALL_AWARDED_DELIVERED 7
+#define AST_CAUSE_NORMAL_CLEARING 16
+#define AST_CAUSE_USER_BUSY 17
+#define AST_CAUSE_NO_USER_RESPONSE 18
+#define AST_CAUSE_NO_ANSWER 19
+#define AST_CAUSE_CALL_REJECTED 21
+#define AST_CAUSE_NUMBER_CHANGED 22
+#define AST_CAUSE_DESTINATION_OUT_OF_ORDER 27
+#define AST_CAUSE_INVALID_NUMBER_FORMAT 28
+#define AST_CAUSE_FACILITY_REJECTED 29
+#define AST_CAUSE_RESPONSE_TO_STATUS_ENQUIRY 30
+#define AST_CAUSE_NORMAL_UNSPECIFIED 31
+#define AST_CAUSE_NORMAL_CIRCUIT_CONGESTION 34
+#define AST_CAUSE_NETWORK_OUT_OF_ORDER 38
+#define AST_CAUSE_NORMAL_TEMPORARY_FAILURE 41
+#define AST_CAUSE_SWITCH_CONGESTION 42
+#define AST_CAUSE_ACCESS_INFO_DISCARDED 43
+#define AST_CAUSE_REQUESTED_CHAN_UNAVAIL 44
+#define AST_CAUSE_PRE_EMPTED 45
+#define AST_CAUSE_FACILITY_NOT_SUBSCRIBED 50
+#define AST_CAUSE_OUTGOING_CALL_BARRED 52
+#define AST_CAUSE_INCOMING_CALL_BARRED 54
+#define AST_CAUSE_BEARERCAPABILITY_NOTAUTH 57
+#define AST_CAUSE_BEARERCAPABILITY_NOTAVAIL 58
+#define AST_CAUSE_BEARERCAPABILITY_NOTIMPL 65
+#define AST_CAUSE_CHAN_NOT_IMPLEMENTED 66
+#define AST_CAUSE_FACILITY_NOT_IMPLEMENTED 69
+#define AST_CAUSE_INVALID_CALL_REFERENCE 81
+#define AST_CAUSE_INCOMPATIBLE_DESTINATION 88
+#define AST_CAUSE_INVALID_MSG_UNSPECIFIED 95
+#define AST_CAUSE_MANDATORY_IE_MISSING 96
+#define AST_CAUSE_MESSAGE_TYPE_NONEXIST 97
+#define AST_CAUSE_WRONG_MESSAGE 98
+#define AST_CAUSE_IE_NONEXIST 99
+#define AST_CAUSE_INVALID_IE_CONTENTS 100
+#define AST_CAUSE_WRONG_CALL_STATE 101
+#define AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE 102
+#define AST_CAUSE_MANDATORY_IE_LENGTH_ERROR 103
+#define AST_CAUSE_PROTOCOL_ERROR 111
+#define AST_CAUSE_INTERWORKING 127
+
+/* Special Asterisk aliases */
+#define AST_CAUSE_BUSY AST_CAUSE_USER_BUSY
+#define AST_CAUSE_FAILURE AST_CAUSE_NETWORK_OUT_OF_ORDER
+#define AST_CAUSE_NORMAL AST_CAUSE_NORMAL_CLEARING
+#define AST_CAUSE_NOANSWER AST_CAUSE_NO_ANSWER
+#define AST_CAUSE_CONGESTION AST_CAUSE_NORMAL_CIRCUIT_CONGESTION
+#define AST_CAUSE_UNREGISTERED AST_CAUSE_NO_ROUTE_DESTINATION
+#define AST_CAUSE_NOTDEFINED 0
+#define AST_CAUSE_NOSUCHDRIVER AST_CAUSE_CHAN_NOT_IMPLEMENTED
+/*@{ */
+
+#endif /* _ASTERISK_CAUSES_H */
diff --git a/trunk/include/asterisk/cdr.h b/trunk/include/asterisk/cdr.h
new file mode 100644
index 000000000..96a5dc497
--- /dev/null
+++ b/trunk/include/asterisk/cdr.h
@@ -0,0 +1,337 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2005, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief Call Detail Record API
+ */
+
+#ifndef _ASTERISK_CDR_H
+#define _ASTERISK_CDR_H
+
+#include <sys/time.h>
+#define AST_CDR_FLAG_KEEP_VARS (1 << 0)
+#define AST_CDR_FLAG_POSTED (1 << 1)
+#define AST_CDR_FLAG_LOCKED (1 << 2)
+#define AST_CDR_FLAG_CHILD (1 << 3)
+#define AST_CDR_FLAG_POST_DISABLED (1 << 4)
+
+/*! \name CDR Flags */
+/*@{ */
+#define AST_CDR_NULL 0
+#define AST_CDR_FAILED (1 << 0)
+#define AST_CDR_BUSY (1 << 1)
+#define AST_CDR_NOANSWER (1 << 2)
+#define AST_CDR_ANSWERED (1 << 3)
+/*@} */
+
+/*! \name CDR AMA Flags */
+/*@{ */
+#define AST_CDR_OMIT (1)
+#define AST_CDR_BILLING (2)
+#define AST_CDR_DOCUMENTATION (3)
+/*@} */
+
+#define AST_MAX_USER_FIELD 256
+#define AST_MAX_ACCOUNT_CODE 20
+
+/* Include channel.h after relevant declarations it will need */
+#include "asterisk/channel.h"
+#include "asterisk/utils.h"
+
+/*! \brief Responsible for call detail data */
+struct ast_cdr {
+ /*! Caller*ID with text */
+ char clid[AST_MAX_EXTENSION];
+ /*! Caller*ID number */
+ char src[AST_MAX_EXTENSION];
+ /*! Destination extension */
+ char dst[AST_MAX_EXTENSION];
+ /*! Destination context */
+ char dcontext[AST_MAX_EXTENSION];
+
+ char channel[AST_MAX_EXTENSION];
+ /*! Destination channel if appropriate */
+ char dstchannel[AST_MAX_EXTENSION];
+ /*! Last application if appropriate */
+ char lastapp[AST_MAX_EXTENSION];
+ /*! Last application data */
+ char lastdata[AST_MAX_EXTENSION];
+
+ struct timeval start;
+
+ struct timeval answer;
+
+ struct timeval end;
+ /*! Total time in system, in seconds */
+ long int duration;
+ /*! Total time call is up, in seconds */
+ long int billsec;
+ /*! What happened to the call */
+ long int disposition;
+ /*! What flags to use */
+ long int amaflags;
+ /*! What account number to use */
+ char accountcode[AST_MAX_ACCOUNT_CODE];
+ /*! flags */
+ unsigned int flags;
+ /*! Unique Channel Identifier */
+ char uniqueid[32];
+ /*! User field */
+ char userfield[AST_MAX_USER_FIELD];
+
+ /*! A linked list for variables */
+ struct varshead varshead;
+
+ struct ast_cdr *next;
+};
+
+void ast_cdr_getvar(struct ast_cdr *cdr, const char *name, char **ret, char *workspace, int workspacelen, int recur, int raw);
+int ast_cdr_setvar(struct ast_cdr *cdr, const char *name, const char *value, int recur);
+int ast_cdr_serialize_variables(struct ast_cdr *cdr, struct ast_str **buf, char delim, char sep, int recur);
+void ast_cdr_free_vars(struct ast_cdr *cdr, int recur);
+int ast_cdr_copy_vars(struct ast_cdr *to_cdr, struct ast_cdr *from_cdr);
+int ast_cdr_log_unanswered(void);
+
+typedef int (*ast_cdrbe)(struct ast_cdr *cdr);
+
+/*! \brief Return TRUE if CDR subsystem is enabled */
+int check_cdr_enabled(void);
+
+/*!
+ * \brief Allocate a CDR record
+ * \retval a malloc'd ast_cdr structure
+ * \retval NULL on error (malloc failure)
+ */
+struct ast_cdr *ast_cdr_alloc(void);
+
+/*!
+ * \brief Duplicate a record
+ * \retval a malloc'd ast_cdr structure,
+ * \retval NULL on error (malloc failure)
+ */
+struct ast_cdr *ast_cdr_dup(struct ast_cdr *cdr);
+
+/*!
+ * \brief Free a CDR record
+ * \param cdr ast_cdr structure to free
+ * Returns nothing
+ */
+void ast_cdr_free(struct ast_cdr *cdr);
+
+/*!
+ * \brief Discard and free a CDR record
+ * \param cdr ast_cdr structure to free
+ * Returns nothing -- same as free, but no checks or complaints
+ */
+void ast_cdr_discard(struct ast_cdr *cdr);
+
+/*!
+ * \brief Initialize based on a channel
+ * \param cdr Call Detail Record to use for channel
+ * \param chan Channel to bind CDR with
+ * Initializes a CDR and associates it with a particular channel
+ * \return 0 by default
+ */
+int ast_cdr_init(struct ast_cdr *cdr, struct ast_channel *chan);
+
+/*!
+ * \brief Initialize based on a channel
+ * \param cdr Call Detail Record to use for channel
+ * \param chan Channel to bind CDR with
+ * Initializes a CDR and associates it with a particular channel
+ * \return 0 by default
+ */
+int ast_cdr_setcid(struct ast_cdr *cdr, struct ast_channel *chan);
+
+/*!
+ * \brief Register a CDR handling engine
+ * \param name name associated with the particular CDR handler
+ * \param desc description of the CDR handler
+ * \param be function pointer to a CDR handler
+ * Used to register a Call Detail Record handler.
+ * \retval 0 on success.
+ * \retval -1 on error
+ */
+int ast_cdr_register(const char *name, const char *desc, ast_cdrbe be);
+
+/*!
+ * \brief Unregister a CDR handling engine
+ * \param name name of CDR handler to unregister
+ * Unregisters a CDR by it's name
+ */
+void ast_cdr_unregister(const char *name);
+
+/*!
+ * \brief Start a call
+ * \param cdr the cdr you wish to associate with the call
+ * Starts all CDR stuff necessary for monitoring a call
+ * Returns nothing
+ */
+void ast_cdr_start(struct ast_cdr *cdr);
+
+/*! \brief Answer a call
+ * \param cdr the cdr you wish to associate with the call
+ * Starts all CDR stuff necessary for doing CDR when answering a call
+ * \note NULL argument is just fine.
+ */
+void ast_cdr_answer(struct ast_cdr *cdr);
+
+/*!
+ * \brief A call wasn't answered
+ * \param cdr the cdr you wish to associate with the call
+ * Marks the channel disposition as "NO ANSWER"
+ */
+extern void ast_cdr_noanswer(struct ast_cdr *cdr);
+
+/*!
+ * \brief Busy a call
+ * \param cdr the cdr you wish to associate with the call
+ * Returns nothing
+ */
+void ast_cdr_busy(struct ast_cdr *cdr);
+
+/*!
+ * \brief Fail a call
+ * \param cdr the cdr you wish to associate with the call
+ * Returns nothing
+ */
+void ast_cdr_failed(struct ast_cdr *cdr);
+
+/*!
+ * \brief Save the result of the call based on the AST_CAUSE_*
+ * \param cdr the cdr you wish to associate with the call
+ * \param cause the AST_CAUSE_*
+ * Returns nothing
+ */
+int ast_cdr_disposition(struct ast_cdr *cdr, int cause);
+
+/*!
+ * \brief End a call
+ * \param cdr the cdr you have associated the call with
+ * Registers the end of call time in the cdr structure.
+ * Returns nothing
+ */
+void ast_cdr_end(struct ast_cdr *cdr);
+
+/*!
+ * \brief Detaches the detail record for posting (and freeing) either now or at a
+ * later time in bulk with other records during batch mode operation.
+ * \param cdr Which CDR to detach from the channel thread
+ * Prevents the channel thread from blocking on the CDR handling
+ * Returns nothing
+ */
+void ast_cdr_detach(struct ast_cdr *cdr);
+
+/*!
+ * \brief Spawns (possibly) a new thread to submit a batch of CDRs to the backend engines
+ * \param shutdown Whether or not we are shutting down
+ * Blocks the asterisk shutdown procedures until the CDR data is submitted.
+ * Returns nothing
+ */
+void ast_cdr_submit_batch(int shutdown);
+
+/*!
+ * \brief Set the destination channel, if there was one
+ * \param cdr Which cdr it's applied to
+ * \param chan Channel to which dest will be
+ * Sets the destination channel the CDR is applied to
+ * Returns nothing
+ */
+void ast_cdr_setdestchan(struct ast_cdr *cdr, const char *chan);
+
+/*!
+ * \brief Set the last executed application
+ * \param cdr which cdr to act upon
+ * \param app the name of the app you wish to change it to
+ * \param data the data you want in the data field of app you set it to
+ * Changes the value of the last executed app
+ * Returns nothing
+ */
+void ast_cdr_setapp(struct ast_cdr *cdr, char *app, char *data);
+
+/*!
+ * \brief Convert a string to a detail record AMA flag
+ * \param flag string form of flag
+ * Converts the string form of the flag to the binary form.
+ * \return the binary form of the flag
+ */
+int ast_cdr_amaflags2int(const char *flag);
+
+/*!
+ * \brief Disposition to a string
+ * \param disposition input binary form
+ * Converts the binary form of a disposition to string form.
+ * \return a pointer to the string form
+ */
+char *ast_cdr_disp2str(int disposition);
+
+/*!
+ * \brief Reset the detail record, optionally posting it first
+ * \param cdr which cdr to act upon
+ * \param flags |AST_CDR_FLAG_POSTED whether or not to post the cdr first before resetting it
+ * |AST_CDR_FLAG_LOCKED whether or not to reset locked CDR's
+ */
+void ast_cdr_reset(struct ast_cdr *cdr, struct ast_flags *flags);
+
+/*!
+ * \brief Flags to a string
+ * \param flags binary flag
+ * Converts binary flags to string flags
+ * Returns string with flag name
+ */
+char *ast_cdr_flags2str(int flags);
+
+/*!
+ * \brief Move the non-null data from the "from" cdr to the "to" cdr
+ * \param to the cdr to get the goodies
+ * \param from the cdr to give the goodies
+ */
+void ast_cdr_merge(struct ast_cdr *to, struct ast_cdr *from);
+
+/*! \brief Set account code, will generate AMI event */
+int ast_cdr_setaccount(struct ast_channel *chan, const char *account);
+
+/*! \brief Set AMA flags for channel */
+int ast_cdr_setamaflags(struct ast_channel *chan, const char *amaflags);
+
+/*! \brief Set CDR user field for channel (stored in CDR) */
+int ast_cdr_setuserfield(struct ast_channel *chan, const char *userfield);
+/*! \brief Append to CDR user field for channel (stored in CDR) */
+int ast_cdr_appenduserfield(struct ast_channel *chan, const char *userfield);
+
+
+/*! Update CDR on a channel */
+int ast_cdr_update(struct ast_channel *chan);
+
+
+extern int ast_default_amaflags;
+
+extern char ast_default_accountcode[AST_MAX_ACCOUNT_CODE];
+
+struct ast_cdr *ast_cdr_append(struct ast_cdr *cdr, struct ast_cdr *newcdr);
+
+/*! \brief Reload the configuration file cdr.conf and start/stop CDR scheduling thread */
+int ast_cdr_engine_reload(void);
+
+/*! \brief Load the configuration file cdr.conf and possibly start the CDR scheduling thread */
+int ast_cdr_engine_init(void);
+
+/*! Submit any remaining CDRs and prepare for shutdown */
+void ast_cdr_engine_term(void);
+
+#endif /* _ASTERISK_CDR_H */
diff --git a/trunk/include/asterisk/channel.h b/trunk/include/asterisk/channel.h
new file mode 100644
index 000000000..efb87fde6
--- /dev/null
+++ b/trunk/include/asterisk/channel.h
@@ -0,0 +1,1577 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2006, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief General Asterisk PBX channel definitions.
+ * \par See also:
+ * \arg \ref Def_Channel
+ * \arg \ref channel_drivers
+ */
+
+/*! \page Def_Channel Asterisk Channels
+ \par What is a Channel?
+ A phone call through Asterisk consists of an incoming
+ connection and an outbound connection. Each call comes
+ in through a channel driver that supports one technology,
+ like SIP, ZAP, IAX2 etc.
+ \par
+ Each channel driver, technology, has it's own private
+ channel or dialog structure, that is technology-dependent.
+ Each private structure is "owned" by a generic Asterisk
+ channel structure, defined in channel.h and handled by
+ channel.c .
+ \par Call scenario
+ This happens when an incoming call arrives to Asterisk
+ -# Call arrives on a channel driver interface
+ -# Channel driver creates a PBX channel and starts a
+ pbx thread on the channel
+ -# The dial plan is executed
+ -# At this point at least two things can happen:
+ -# The call is answered by Asterisk and
+ Asterisk plays a media stream or reads media
+ -# The dial plan forces Asterisk to create an outbound
+ call somewhere with the dial (see \ref app_dial.c)
+ application
+ .
+
+ \par Bridging channels
+ If Asterisk dials out this happens:
+ -# Dial creates an outbound PBX channel and asks one of the
+ channel drivers to create a call
+ -# When the call is answered, Asterisk bridges the media streams
+ so the caller on the first channel can speak with the callee
+ on the second, outbound channel
+ -# In some cases where we have the same technology on both
+ channels and compatible codecs, a native bridge is used.
+ In a native bridge, the channel driver handles forwarding
+ of incoming audio to the outbound stream internally, without
+ sending audio frames through the PBX.
+ -# In SIP, theres an "external native bridge" where Asterisk
+ redirects the endpoint, so audio flows directly between the
+ caller's phone and the callee's phone. Signalling stays in
+ Asterisk in order to be able to provide a proper CDR record
+ for the call.
+
+
+ \par Masquerading channels
+ In some cases, a channel can masquerade itself into another
+ channel. This happens frequently in call transfers, where
+ a new channel takes over a channel that is already involved
+ in a call. The new channel sneaks in and takes over the bridge
+ and the old channel, now a zombie, is hung up.
+
+ \par Reference
+ \arg channel.c - generic functions
+ \arg channel.h - declarations of functions, flags and structures
+ \arg translate.h - Transcoding support functions
+ \arg \ref channel_drivers - Implemented channel drivers
+ \arg \ref Def_Frame Asterisk Multimedia Frames
+ \arg \ref Def_Bridge
+
+*/
+/*! \page Def_Bridge Asterisk Channel Bridges
+
+ In Asterisk, there's several media bridges.
+
+ The Core bridge handles two channels (a "phone call") and bridge
+ them together.
+
+ The conference bridge (meetme) handles several channels simultaneously
+ with the support of an external timer (zaptel timer). This is used
+ not only by the Conference application (meetme) but also by the
+ page application and the SLA system introduced in 1.4.
+ The conference bridge does not handle video.
+
+ When two channels of the same type connect, the channel driver
+ or the media subsystem used by the channel driver (i.e. RTP)
+ can create a native bridge without sending media through the
+ core.
+
+ Native briding can be disabled by a number of reasons,
+ like DTMF being needed by the core or codecs being incompatible
+ so a transcoding module is needed.
+
+References:
+ \li \see ast_channel_early_bridge()
+ \li \see ast_channel_bridge()
+ \li \see app_meetme.c
+ \li \ref AstRTPbridge
+ \li \see ast_rtp_bridge()
+ \li \ref Def_Channel
+*/
+
+/*! \page AstFileDesc File descriptors
+ Asterisk File descriptors are connected to each channel (see \ref Def_Channel)
+ in the \ref ast_channel structure.
+*/
+
+#ifndef _ASTERISK_CHANNEL_H
+#define _ASTERISK_CHANNEL_H
+
+#include "asterisk/abstract_jb.h"
+
+#ifdef HAVE_SYS_POLL_H
+#include <sys/poll.h>
+#else
+#include "asterisk/poll-compat.h"
+#endif
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+#define AST_MAX_EXTENSION 80 /*!< Max length of an extension */
+#define AST_MAX_CONTEXT 80 /*!< Max length of a context */
+#define AST_CHANNEL_NAME 80 /*!< Max length of an ast_channel name */
+#define MAX_LANGUAGE 20 /*!< Max length of the language setting */
+#define MAX_MUSICCLASS 80 /*!< Max length of the music class setting */
+
+#include "asterisk/frame.h"
+#include "asterisk/sched.h"
+#include "asterisk/chanvars.h"
+#include "asterisk/config.h"
+#include "asterisk/lock.h"
+#include "asterisk/cdr.h"
+#include "asterisk/utils.h"
+#include "asterisk/linkedlists.h"
+#include "asterisk/stringfields.h"
+
+#define DATASTORE_INHERIT_FOREVER INT_MAX
+
+#define AST_MAX_FDS 10
+/*
+ * We have AST_MAX_FDS file descriptors in a channel.
+ * Some of them have a fixed use:
+ */
+#define AST_ALERT_FD (AST_MAX_FDS-1) /*!< used for alertpipe */
+#define AST_TIMING_FD (AST_MAX_FDS-2) /*!< used for timingfd */
+#define AST_AGENT_FD (AST_MAX_FDS-3) /*!< used by agents for pass through */
+#define AST_GENERATOR_FD (AST_MAX_FDS-4) /*!< used by generator */
+
+enum ast_bridge_result {
+ AST_BRIDGE_COMPLETE = 0,
+ AST_BRIDGE_FAILED = -1,
+ AST_BRIDGE_FAILED_NOWARN = -2,
+ AST_BRIDGE_RETRY = -3,
+};
+
+typedef unsigned long long ast_group_t;
+
+/*! \todo Add an explanation of an Asterisk generator
+*/
+struct ast_generator {
+ void *(*alloc)(struct ast_channel *chan, void *params);
+ void (*release)(struct ast_channel *chan, void *data);
+ /*! This function gets called with the channel locked */
+ int (*generate)(struct ast_channel *chan, void *data, int len, int samples);
+ /*! This gets called when DTMF_END frames are read from the channel */
+ void (*digit)(struct ast_channel *chan, char digit);
+};
+
+/*! \brief Structure for a data store type */
+struct ast_datastore_info {
+ const char *type; /*!< Type of data store */
+ void *(*duplicate)(void *data); /*!< Duplicate item data (used for inheritance) */
+ void (*destroy)(void *data); /*!< Destroy function */
+};
+
+/*! \brief Structure for a channel data store */
+struct ast_datastore {
+ const char *uid; /*!< Unique data store identifier */
+ void *data; /*!< Contained data */
+ const struct ast_datastore_info *info; /*!< Data store type information */
+ unsigned int inheritance; /*!< Number of levels this item will continue to be inherited */
+ AST_LIST_ENTRY(ast_datastore) entry; /*!< Used for easy linking */
+};
+
+/*! \brief Structure for all kinds of caller ID identifications.
+ * \note All string fields here are malloc'ed, so they need to be
+ * freed when the structure is deleted.
+ * Also, NULL and "" must be considered equivalent.
+ *
+ * SIP and IAX2 has utf8 encoded Unicode caller ID names.
+ * In some cases, we also have an alternative (RPID) E.164 number that can be used
+ * as caller ID on numeric E.164 phone networks (zaptel or SIP/IAX2 to pstn gateway).
+ *
+ * \todo Implement settings for transliteration between UTF8 caller ID names in
+ * to Ascii Caller ID's (Zaptel). Östen Åsklund might be transliterated into
+ * Osten Asklund or Oesten Aasklund depending upon language and person...
+ * We need automatic routines for incoming calls and static settings for
+ * our own accounts.
+ */
+struct ast_callerid {
+ char *cid_dnid; /*!< Malloc'd Dialed Number Identifier */
+ char *cid_num; /*!< Malloc'd Caller Number */
+ char *cid_name; /*!< Malloc'd Caller Name (ASCII) */
+ char *cid_ani; /*!< Malloc'd ANI */
+ char *cid_rdnis; /*!< Malloc'd RDNIS */
+ int cid_pres; /*!< Callerid presentation/screening */
+ int cid_ani2; /*!< Callerid ANI 2 (Info digits) */
+ int cid_ton; /*!< Callerid Type of Number */
+ int cid_tns; /*!< Callerid Transit Network Select */
+};
+
+/*! \brief
+ Structure to describe a channel "technology", ie a channel driver
+ See for examples:
+ \arg chan_iax2.c - The Inter-Asterisk exchange protocol
+ \arg chan_sip.c - The SIP channel driver
+ \arg chan_zap.c - PSTN connectivity (TDM, PRI, T1/E1, FXO, FXS)
+
+ If you develop your own channel driver, this is where you
+ tell the PBX at registration of your driver what properties
+ this driver supports and where different callbacks are
+ implemented.
+*/
+struct ast_channel_tech {
+ const char * const type;
+ const char * const description;
+
+ int capabilities; /*!< Bitmap of formats this channel can handle */
+
+ int properties; /*!< Technology Properties */
+
+ /*! \brief Requester - to set up call data structures (pvt's) */
+ struct ast_channel *(* const requester)(const char *type, int format, void *data, int *cause);
+
+ int (* const devicestate)(void *data); /*!< Devicestate call back */
+
+ /*!
+ * \brief Start sending a literal DTMF digit
+ *
+ * \note The channel is not locked when this function gets called.
+ */
+ int (* const send_digit_begin)(struct ast_channel *chan, char digit);
+
+ /*!
+ * \brief Stop sending a literal DTMF digit
+ *
+ * \note The channel is not locked when this function gets called.
+ */
+ int (* const send_digit_end)(struct ast_channel *chan, char digit, unsigned int duration);
+
+ /*! \brief Call a given phone number (address, etc), but don't
+ take longer than timeout seconds to do so. */
+ int (* const call)(struct ast_channel *chan, char *addr, int timeout);
+
+ /*! \brief Hangup (and possibly destroy) the channel */
+ int (* const hangup)(struct ast_channel *chan);
+
+ /*! \brief Answer the channel */
+ int (* const answer)(struct ast_channel *chan);
+
+ /*! \brief Read a frame, in standard format (see frame.h) */
+ struct ast_frame * (* const read)(struct ast_channel *chan);
+
+ /*! \brief Write a frame, in standard format (see frame.h) */
+ int (* const write)(struct ast_channel *chan, struct ast_frame *frame);
+
+ /*! \brief Display or transmit text */
+ int (* const send_text)(struct ast_channel *chan, const char *text);
+
+ /*! \brief Display or send an image */
+ int (* const send_image)(struct ast_channel *chan, struct ast_frame *frame);
+
+ /*! \brief Send HTML data */
+ int (* const send_html)(struct ast_channel *chan, int subclass, const char *data, int len);
+
+ /*! \brief Handle an exception, reading a frame */
+ struct ast_frame * (* const exception)(struct ast_channel *chan);
+
+ /*! \brief Bridge two channels of the same type together */
+ enum ast_bridge_result (* const bridge)(struct ast_channel *c0, struct ast_channel *c1, int flags,
+ struct ast_frame **fo, struct ast_channel **rc, int timeoutms);
+
+ /*! \brief Bridge two channels of the same type together (early) */
+ enum ast_bridge_result (* const early_bridge)(struct ast_channel *c0, struct ast_channel *c1);
+
+ /*! \brief Indicate a particular condition (e.g. AST_CONTROL_BUSY or AST_CONTROL_RINGING or AST_CONTROL_CONGESTION */
+ int (* const indicate)(struct ast_channel *c, int condition, const void *data, size_t datalen);
+
+ /*! \brief Fix up a channel: If a channel is consumed, this is called. Basically update any ->owner links */
+ int (* const fixup)(struct ast_channel *oldchan, struct ast_channel *newchan);
+
+ /*! \brief Set a given option */
+ int (* const setoption)(struct ast_channel *chan, int option, void *data, int datalen);
+
+ /*! \brief Query a given option */
+ int (* const queryoption)(struct ast_channel *chan, int option, void *data, int *datalen);
+
+ /*! \brief Blind transfer other side (see app_transfer.c and ast_transfer() */
+ int (* const transfer)(struct ast_channel *chan, const char *newdest);
+
+ /*! \brief Write a frame, in standard format */
+ int (* const write_video)(struct ast_channel *chan, struct ast_frame *frame);
+
+ /*! \brief Write a text frame, in standard format */
+ int (* const write_text)(struct ast_channel *chan, struct ast_frame *frame);
+
+ /*! \brief Find bridged channel */
+ struct ast_channel *(* const bridged_channel)(struct ast_channel *chan, struct ast_channel *bridge);
+
+ /*! \brief Provide additional read items for CHANNEL() dialplan function */
+ int (* func_channel_read)(struct ast_channel *chan, const char *function, char *data, char *buf, size_t len);
+
+ /*! \brief Provide additional write items for CHANNEL() dialplan function */
+ int (* func_channel_write)(struct ast_channel *chan, const char *function, char *data, const char *value);
+
+ /*! \brief Retrieve base channel (agent and local) */
+ struct ast_channel* (* get_base_channel)(struct ast_channel *chan);
+
+ /*! \brief Set base channel (agent and local) */
+ int (* set_base_channel)(struct ast_channel *chan, struct ast_channel *base);
+};
+
+struct ast_epoll_data;
+
+/*!
+ * The high bit of the frame count is used as a debug marker, so
+ * increments of the counters must be done with care.
+ * Please use c->fin = FRAMECOUNT_INC(c->fin) and the same for c->fout.
+ */
+#define DEBUGCHAN_FLAG 0x80000000
+
+/* XXX not ideal to evaluate x twice... */
+#define FRAMECOUNT_INC(x) ( ((x) & DEBUGCHAN_FLAG) | (((x)+1) & ~DEBUGCHAN_FLAG) )
+
+/*!
+ * The current value of the debug flags is stored in the two
+ * variables global_fin and global_fout (declared in main/channel.c)
+ */
+extern unsigned long global_fin, global_fout;
+
+enum ast_channel_adsicpe {
+ AST_ADSI_UNKNOWN,
+ AST_ADSI_AVAILABLE,
+ AST_ADSI_UNAVAILABLE,
+ AST_ADSI_OFFHOOKONLY,
+};
+
+/*!
+ * \brief ast_channel states
+ *
+ * \note Bits 0-15 of state are reserved for the state (up/down) of the line
+ * Bits 16-32 of state are reserved for flags
+ */
+enum ast_channel_state {
+ AST_STATE_DOWN, /*!< Channel is down and available */
+ AST_STATE_RESERVED, /*!< Channel is down, but reserved */
+ AST_STATE_OFFHOOK, /*!< Channel is off hook */
+ AST_STATE_DIALING, /*!< Digits (or equivalent) have been dialed */
+ AST_STATE_RING, /*!< Line is ringing */
+ AST_STATE_RINGING, /*!< Remote end is ringing */
+ AST_STATE_UP, /*!< Line is up */
+ AST_STATE_BUSY, /*!< Line is busy */
+ AST_STATE_DIALING_OFFHOOK, /*!< Digits (or equivalent) have been dialed while offhook */
+ AST_STATE_PRERING, /*!< Channel has detected an incoming call and is waiting for ring */
+
+ AST_STATE_MUTE = (1 << 16), /*!< Do not transmit voice data */
+};
+
+/*! \brief Main Channel structure associated with a channel.
+ * This is the side of it mostly used by the pbx and call management.
+ *
+ * \note XXX It is important to remember to increment .cleancount each time
+ * this structure is changed. XXX
+ */
+
+struct ast_channel {
+ const struct ast_channel_tech *tech; /*!< Technology (point to channel driver) */
+
+ void *tech_pvt; /*!< Private data used by the technology driver */
+
+ AST_DECLARE_STRING_FIELDS(
+ AST_STRING_FIELD(name); /*!< ASCII unique channel name */
+ AST_STRING_FIELD(language); /*!< Language requested for voice prompts */
+ AST_STRING_FIELD(musicclass); /*!< Default music class */
+ AST_STRING_FIELD(accountcode); /*!< Account code for billing */
+ AST_STRING_FIELD(call_forward); /*!< Where to forward to if asked to dial on this interface */
+ AST_STRING_FIELD(uniqueid); /*!< Unique Channel Identifier */
+ );
+
+ int fds[AST_MAX_FDS]; /*!< File descriptors for channel -- Drivers will poll on
+ these file descriptors, so at least one must be non -1.
+ See \arg \ref AstFileDesc */
+
+ void *music_state; /*!< Music State*/
+ void *generatordata; /*!< Current generator data if there is any */
+ struct ast_generator *generator; /*!< Current active data generator */
+
+ struct ast_channel *_bridge; /*!< Who are we bridged to, if we're bridged.
+ Who is proxying for us, if we are proxied (i.e. chan_agent).
+ Do not access directly, use ast_bridged_channel(chan) */
+
+ struct ast_channel *masq; /*!< Channel that will masquerade as us */
+ struct ast_channel *masqr; /*!< Who we are masquerading as */
+ int cdrflags; /*!< Call Detail Record Flags */
+
+ int _softhangup; /*!< Whether or not we have been hung up... Do not set this value
+ directly, use ast_softhangup() */
+ time_t whentohangup; /*!< Non-zero, set to actual time when channel is to be hung up */
+ pthread_t blocker; /*!< If anyone is blocking, this is them */
+ ast_mutex_t lock_dont_use; /*!< Lock a channel for some operations. See ast_channel_lock() */
+ const char *blockproc; /*!< Procedure causing blocking */
+
+ const char *appl; /*!< Current application */
+ const char *data; /*!< Data passed to current application */
+ int fdno; /*!< Which fd had an event detected on */
+ struct sched_context *sched; /*!< Schedule context */
+ int streamid; /*!< For streaming playback, the schedule ID */
+ struct ast_filestream *stream; /*!< Stream itself. */
+ int vstreamid; /*!< For streaming video playback, the schedule ID */
+ struct ast_filestream *vstream; /*!< Video Stream itself. */
+ int oldwriteformat; /*!< Original writer format */
+
+ int timingfd; /*!< Timing fd */
+ int (*timingfunc)(const void *data);
+ void *timingdata;
+
+ enum ast_channel_state _state; /*!< State of line -- Don't write directly, use ast_setstate() */
+ int rings; /*!< Number of rings so far */
+ struct ast_callerid cid; /*!< Caller ID, name, presentation etc */
+ char dtmfq[AST_MAX_EXTENSION]; /*!< Any/all queued DTMF characters */
+ struct ast_frame dtmff; /*!< DTMF frame */
+
+ char context[AST_MAX_CONTEXT]; /*!< Dialplan: Current extension context */
+ char exten[AST_MAX_EXTENSION]; /*!< Dialplan: Current extension number */
+ int priority; /*!< Dialplan: Current extension priority */
+ char macrocontext[AST_MAX_CONTEXT]; /*!< Macro: Current non-macro context. See app_macro.c */
+ char macroexten[AST_MAX_EXTENSION]; /*!< Macro: Current non-macro extension. See app_macro.c */
+ int macropriority; /*!< Macro: Current non-macro priority. See app_macro.c */
+ char dialcontext[AST_MAX_CONTEXT]; /*!< Dial: Extension context that we were called from */
+
+ struct ast_pbx *pbx; /*!< PBX private structure for this channel */
+ int amaflags; /*!< Set BEFORE PBX is started to determine AMA flags */
+ struct ast_cdr *cdr; /*!< Call Detail Record */
+ enum ast_channel_adsicpe adsicpe; /*!< Whether or not ADSI is detected on CPE */
+
+ struct ind_tone_zone *zone; /*!< Tone zone as set in indications.conf or
+ in the CHANNEL dialplan function */
+
+ struct ast_channel_monitor *monitor; /*!< Channel monitoring */
+
+ unsigned long insmpl; /*!< Track the read/written samples for monitor use */
+ unsigned long outsmpl; /*!< Track the read/written samples for monitor use */
+
+ unsigned int fin; /*!< Frames in counters. The high bit is a debug mask, so
+ the counter is only in the remaining bits */
+ unsigned int fout; /*!< Frames out counters. The high bit is a debug mask, so
+ the counter is only in the remaining bits */
+ int hangupcause; /*!< Why is the channel hanged up. See causes.h */
+ struct varshead varshead; /*!< A linked list for channel variables. See \ref AstChanVar */
+ ast_group_t callgroup; /*!< Call group for call pickups */
+ ast_group_t pickupgroup; /*!< Pickup group - which calls groups can be picked up? */
+ unsigned int flags; /*!< channel flags of AST_FLAG_ type */
+ unsigned short transfercapability; /*!< ISDN Transfer Capbility - AST_FLAG_DIGITAL is not enough */
+ AST_LIST_HEAD_NOLOCK(, ast_frame) readq;
+ int alertpipe[2];
+
+ int nativeformats; /*!< Kinds of data this channel can natively handle */
+ int readformat; /*!< Requested read format */
+ int writeformat; /*!< Requested write format */
+ struct ast_trans_pvt *writetrans; /*!< Write translation path */
+ struct ast_trans_pvt *readtrans; /*!< Read translation path */
+ int rawreadformat; /*!< Raw read format */
+ int rawwriteformat; /*!< Raw write format */
+
+ struct ast_audiohook_list *audiohooks;
+
+ AST_LIST_ENTRY(ast_channel) chan_list; /*!< For easy linking */
+
+ struct ast_jb jb; /*!< The jitterbuffer state */
+
+ char emulate_dtmf_digit; /*!< Digit being emulated */
+ unsigned int emulate_dtmf_duration; /*!< Number of ms left to emulate DTMF for */
+ struct timeval dtmf_tv; /*!< The time that an in process digit began, or the last digit ended */
+
+ AST_LIST_HEAD_NOLOCK(datastores, ast_datastore) datastores; /*!< Data stores on the channel */
+
+#ifdef HAVE_EPOLL
+ int epfd;
+ struct ast_epoll_data *epfd_data[AST_MAX_FDS];
+#endif
+ int visible_indication; /*!< Indication currently playing on the channel */
+};
+
+/*! \brief ast_channel_tech Properties */
+enum {
+ /*! \brief Channels have this property if they can accept input with jitter;
+ * i.e. most VoIP channels */
+ AST_CHAN_TP_WANTSJITTER = (1 << 0),
+ /*! \brief Channels have this property if they can create jitter;
+ * i.e. most VoIP channels */
+ AST_CHAN_TP_CREATESJITTER = (1 << 1),
+};
+
+/*! \brief ast_channel flags */
+enum {
+ /*! Queue incoming dtmf, to be released when this flag is turned off */
+ AST_FLAG_DEFER_DTMF = (1 << 1),
+ /*! write should be interrupt generator */
+ AST_FLAG_WRITE_INT = (1 << 2),
+ /*! a thread is blocking on this channel */
+ AST_FLAG_BLOCKING = (1 << 3),
+ /*! This is a zombie channel */
+ AST_FLAG_ZOMBIE = (1 << 4),
+ /*! There is an exception pending */
+ AST_FLAG_EXCEPTION = (1 << 5),
+ /*! Listening to moh XXX anthm promises me this will disappear XXX */
+ AST_FLAG_MOH = (1 << 6),
+ /*! This channel is spying on another channel */
+ AST_FLAG_SPYING = (1 << 7),
+ /*! This channel is in a native bridge */
+ AST_FLAG_NBRIDGE = (1 << 8),
+ /*! the channel is in an auto-incrementing dialplan processor,
+ * so when ->priority is set, it will get incremented before
+ * finding the next priority to run */
+ AST_FLAG_IN_AUTOLOOP = (1 << 9),
+ /*! This is an outgoing call */
+ AST_FLAG_OUTGOING = (1 << 10),
+ /*! A DTMF_BEGIN frame has been read from this channel, but not yet an END */
+ AST_FLAG_IN_DTMF = (1 << 12),
+ /*! A DTMF_END was received when not IN_DTMF, so the length of the digit is
+ * currently being emulated */
+ AST_FLAG_EMULATE_DTMF = (1 << 13),
+ /*! This is set to tell the channel not to generate DTMF begin frames, and
+ * to instead only generate END frames. */
+ AST_FLAG_END_DTMF_ONLY = (1 << 14),
+ /*! Flag to show channels that this call is hangup due to the fact that the call
+ was indeed anwered, but in another channel */
+ AST_FLAG_ANSWERED_ELSEWHERE = (1 << 15),
+ /*! This flag indicates that on a masquerade, an active stream should not
+ * be carried over */
+ AST_FLAG_MASQ_NOSTREAM = (1 << 16),
+};
+
+/*! \brief ast_bridge_config flags */
+enum {
+ AST_FEATURE_PLAY_WARNING = (1 << 0),
+ AST_FEATURE_REDIRECT = (1 << 1),
+ AST_FEATURE_DISCONNECT = (1 << 2),
+ AST_FEATURE_ATXFER = (1 << 3),
+ AST_FEATURE_AUTOMON = (1 << 4),
+ AST_FEATURE_PARKCALL = (1 << 5),
+ AST_FEATURE_AUTOMIXMON = (1 << 6),
+};
+
+/*! \brief bridge configuration */
+struct ast_bridge_config {
+ struct ast_flags features_caller;
+ struct ast_flags features_callee;
+ struct timeval start_time;
+ long feature_timer;
+ long timelimit;
+ long play_warning;
+ long warning_freq;
+ const char *warning_sound;
+ const char *end_sound;
+ const char *start_sound;
+ int firstpass;
+ unsigned int flags;
+};
+
+struct chanmon;
+
+struct outgoing_helper {
+ const char *context;
+ const char *exten;
+ int priority;
+ const char *cid_num;
+ const char *cid_name;
+ const char *account;
+ struct ast_variable *vars;
+ struct ast_channel *parent_channel;
+};
+
+enum {
+ AST_CDR_TRANSFER = (1 << 0),
+ AST_CDR_FORWARD = (1 << 1),
+ AST_CDR_CALLWAIT = (1 << 2),
+ AST_CDR_CONFERENCE = (1 << 3),
+};
+
+enum {
+ /*! Soft hangup by device */
+ AST_SOFTHANGUP_DEV = (1 << 0),
+ /*! Soft hangup for async goto */
+ AST_SOFTHANGUP_ASYNCGOTO = (1 << 1),
+ AST_SOFTHANGUP_SHUTDOWN = (1 << 2),
+ AST_SOFTHANGUP_TIMEOUT = (1 << 3),
+ AST_SOFTHANGUP_APPUNLOAD = (1 << 4),
+ AST_SOFTHANGUP_EXPLICIT = (1 << 5),
+ AST_SOFTHANGUP_UNBRIDGE = (1 << 6),
+};
+
+
+/*! \brief Channel reload reasons for manager events at load or reload of configuration */
+enum channelreloadreason {
+ CHANNEL_MODULE_LOAD,
+ CHANNEL_MODULE_RELOAD,
+ CHANNEL_CLI_RELOAD,
+ CHANNEL_MANAGER_RELOAD,
+};
+
+/*!
+ * \brief Create a channel datastore structure
+ *
+ * \note None of the datastore API calls lock the ast_channel they are using.
+ * So, the channel should be locked before calling the functions that
+ * take a channel argument.
+ */
+struct ast_datastore *ast_channel_datastore_alloc(const struct ast_datastore_info *info, const char *uid);
+
+/*! \brief Free a channel datastore structure */
+int ast_channel_datastore_free(struct ast_datastore *datastore);
+
+/*! \brief Inherit datastores from a parent to a child. */
+int ast_channel_datastore_inherit(struct ast_channel *from, struct ast_channel *to);
+
+/*!
+ * \brief Add a datastore to a channel
+ *
+ * \note The channel should be locked before calling this function.
+ *
+ * \retval 0 success
+ * \retval non-zero failure
+ */
+
+int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore);
+
+/*!
+ * \brief Remove a datastore from a channel
+ *
+ * \note The channel should be locked before calling this function.
+ *
+ * \retval 0 success
+ * \retval non-zero failure
+ */
+int ast_channel_datastore_remove(struct ast_channel *chan, struct ast_datastore *datastore);
+
+/*!
+ * \brief Find a datastore on a channel
+ *
+ * \note The channel should be locked before calling this function.
+ *
+ * \note The datastore returned from this function must not be used if the
+ * reference to the channel is released.
+ */
+struct ast_datastore *ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid);
+
+/*! \brief Change the state of a channel */
+int ast_setstate(struct ast_channel *chan, enum ast_channel_state);
+
+/*!
+ * \brief Create a channel structure
+ *
+ * \retval NULL failure
+ * \retval non-NULL successfully allocated channel
+ *
+ * \note By default, new channels are set to the "s" extension
+ * and "default" context.
+ */
+struct ast_channel *ast_channel_alloc(int needqueue, int state, const char *cid_num, const char *cid_name, const char *acctcode, const char *exten, const char *context, const int amaflag, const char *name_fmt, ...);
+
+/*!
+ * \brief Queue an outgoing frame
+ *
+ * \note The channel does not need to be locked before calling this function.
+ */
+int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f);
+
+/*!
+ * \brief Queue a hangup frame
+ *
+ * \note The channel does not need to be locked before calling this function.
+ */
+int ast_queue_hangup(struct ast_channel *chan);
+
+/*!
+ * \brief Queue a control frame with payload
+ *
+ * \param chan channel to queue frame onto
+ * \param control type of control frame
+ *
+ * \note The channel does not need to be locked before calling this function.
+ *
+ * \retval zero on success
+ * \retval non-zero on failure
+ */
+int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control);
+
+/*!
+ * \brief Queue a control frame with payload
+ *
+ * \param chan channel to queue frame onto
+ * \param control type of control frame
+ * \param data pointer to payload data to be included in frame
+ * \param datalen number of bytes of payload data
+ *
+ * \retval 0 success
+ * \retval non-zero failure
+ *
+ * The supplied payload data is copied into the frame, so the caller's copy
+ * is not modified nor freed, and the resulting frame will retain a copy of
+ * the data even if the caller frees their local copy.
+ *
+ * \note This method should be treated as a 'network transport'; in other
+ * words, your frames may be transferred across an IAX2 channel to another
+ * system, which may be a different endianness than yours. Because of this,
+ * you should ensure that either your frames will never be expected to work
+ * across systems, or that you always put your payload data into 'network byte
+ * order' before calling this function.
+ *
+ * \note The channel does not need to be locked before calling this function.
+ */
+int ast_queue_control_data(struct ast_channel *chan, enum ast_control_frame_type control,
+ const void *data, size_t datalen);
+
+/*!
+ * \brief Change channel name
+ *
+ * \note The channel must be locked before calling this function.
+ */
+void ast_change_name(struct ast_channel *chan, char *newname);
+
+/*! \brief Free a channel structure */
+void ast_channel_free(struct ast_channel *);
+
+/*!
+ * \brief Requests a channel
+ *
+ * \param type type of channel to request
+ * \param format requested channel format (codec)
+ * \param data data to pass to the channel requester
+ * \param status status
+ *
+ * Request a channel of a given type, with data as optional information used
+ * by the low level module
+ *
+ * \retval NULL failure
+ * \retval non-NULL channel on success
+ */
+struct ast_channel *ast_request(const char *type, int format, void *data, int *status);
+
+/*!
+ * \brief Request a channel of a given type, with data as optional information used
+ * by the low level module and attempt to place a call on it
+ *
+ * \param type type of channel to request
+ * \param format requested channel format
+ * \param data data to pass to the channel requester
+ * \param timeout maximum amount of time to wait for an answer
+ * \param reason why unsuccessful (if unsuccessful)
+ * \param cid_num Caller-ID Number
+ * \param cid_name Caller-ID Name (ascii)
+ *
+ * \return Returns an ast_channel on success or no answer, NULL on failure. Check the value of chan->_state
+ * to know if the call was answered or not.
+ */
+struct ast_channel *ast_request_and_dial(const char *type, int format, void *data,
+ int timeout, int *reason, const char *cid_num, const char *cid_name);
+
+/*!
+ * \brief Request a channel of a given type, with data as optional information used
+ * by the low level module and attempt to place a call on it
+ * \param type type of channel to request
+ * \param format requested channel format
+ * \param data data to pass to the channel requester
+ * \param timeout maximum amount of time to wait for an answer
+ * \param reason why unsuccessful (if unsuccessful)
+ * \param cid_num Caller-ID Number
+ * \param cid_name Caller-ID Name (ascii)
+ * \param oh Outgoing helper
+ * \return Returns an ast_channel on success or no answer, NULL on failure. Check the value of chan->_state
+ * to know if the call was answered or not.
+ */
+struct ast_channel *__ast_request_and_dial(const char *type, int format, void *data,
+ int timeout, int *reason, const char *cid_num, const char *cid_name, struct outgoing_helper *oh);
+
+/*!\brief Register a channel technology (a new channel driver)
+ * Called by a channel module to register the kind of channels it supports.
+ * \param tech Structure defining channel technology or "type"
+ * \return Returns 0 on success, -1 on failure.
+ */
+int ast_channel_register(const struct ast_channel_tech *tech);
+
+/*! \brief Unregister a channel technology
+ * \param tech Structure defining channel technology or "type" that was previously registered
+ * \return No return value.
+ */
+void ast_channel_unregister(const struct ast_channel_tech *tech);
+
+/*! \brief Get a channel technology structure by name
+ * \param name name of technology to find
+ * \return a pointer to the structure, or NULL if no matching technology found
+ */
+const struct ast_channel_tech *ast_get_channel_tech(const char *name);
+
+/*! \brief Hang up a channel
+ * \note This function performs a hard hangup on a channel. Unlike the soft-hangup, this function
+ * performs all stream stopping, etc, on the channel that needs to end.
+ * chan is no longer valid after this call.
+ * \param chan channel to hang up
+ * \return Returns 0 on success, -1 on failure.
+ */
+int ast_hangup(struct ast_channel *chan);
+
+/*!
+ * \brief Softly hangup up a channel
+ *
+ * \param chan channel to be soft-hung-up
+ * \param cause Ast hangupcause for hangup
+ *
+ * Call the protocol layer, but don't destroy the channel structure
+ * (use this if you are trying to
+ * safely hangup a channel managed by another thread.
+ *
+ * \note The channel passed to this function does not need to be locked.
+ *
+ * \return Returns 0 regardless
+ */
+int ast_softhangup(struct ast_channel *chan, int cause);
+
+/*! \brief Softly hangup up a channel (no channel lock)
+ * \param chan channel to be soft-hung-up
+ * \param cause Ast hangupcause for hangup (see cause.h) */
+int ast_softhangup_nolock(struct ast_channel *chan, int cause);
+
+/*! \brief Check to see if a channel is needing hang up
+ * \param chan channel on which to check for hang up
+ * This function determines if the channel is being requested to be hung up.
+ * \return Returns 0 if not, or 1 if hang up is requested (including time-out).
+ */
+int ast_check_hangup(struct ast_channel *chan);
+
+/*! \brief Compare a offset with the settings of when to hang a channel up
+ * \param chan channel on which to check for hang up
+ * \param offset offset in seconds from current time
+ * \return 1, 0, or -1
+ * This function compares a offset from current time with the absolute time
+ * out on a channel (when to hang up). If the absolute time out on a channel
+ * is earlier than current time plus the offset, it returns 1, if the two
+ * time values are equal, it return 0, otherwise, it return -1.
+ */
+int ast_channel_cmpwhentohangup(struct ast_channel *chan, time_t offset);
+
+/*! \brief Set when to hang a channel up
+ *
+ * \param chan channel on which to check for hang up
+ * \param offset offset in seconds from current time of when to hang up
+ *
+ * This function sets the absolute time out on a channel (when to hang up).
+ *
+ * \note This function does not require that the channel is locked before
+ * calling it.
+ *
+ * \return Nothing
+ */
+void ast_channel_setwhentohangup(struct ast_channel *chan, time_t offset);
+
+/*!
+ * \brief Answer a channel
+ *
+ * \param chan channel to answer
+ *
+ * This function answers a channel and handles all necessary call
+ * setup functions.
+ *
+ * \note The channel passed does not need to be locked.
+ *
+ * \retval 0 on success
+ * \retval non-zero on failure
+ */
+int ast_answer(struct ast_channel *chan);
+int __ast_answer(struct ast_channel *chan, unsigned int delay);
+
+/*! \brief Make a call
+ * \param chan which channel to make the call on
+ * \param addr destination of the call
+ * \param timeout time to wait on for connect
+ * Place a call, take no longer than timeout ms.
+ \return Returns -1 on failure, 0 on not enough time
+ (does not automatically stop ringing), and
+ the number of seconds the connect took otherwise.
+ */
+int ast_call(struct ast_channel *chan, char *addr, int timeout);
+
+/*! \brief Indicates condition of channel
+ * \note Indicate a condition such as AST_CONTROL_BUSY, AST_CONTROL_RINGING, or AST_CONTROL_CONGESTION on a channel
+ * \param chan channel to change the indication
+ * \param condition which condition to indicate on the channel
+ * \return Returns 0 on success, -1 on failure
+ */
+int ast_indicate(struct ast_channel *chan, int condition);
+
+/*! \brief Indicates condition of channel, with payload
+ * \note Indicate a condition such as AST_CONTROL_HOLD with payload being music on hold class
+ * \param chan channel to change the indication
+ * \param condition which condition to indicate on the channel
+ * \param data pointer to payload data
+ * \param datalen size of payload data
+ * \return Returns 0 on success, -1 on failure
+ */
+int ast_indicate_data(struct ast_channel *chan, int condition, const void *data, size_t datalen);
+
+/* Misc stuff ------------------------------------------------ */
+
+/*! \brief Wait for input on a channel
+ * \param chan channel to wait on
+ * \param ms length of time to wait on the channel
+ * Wait for input on a channel for a given # of milliseconds (<0 for indefinite).
+ \return Returns < 0 on failure, 0 if nothing ever arrived, and the # of ms remaining otherwise */
+int ast_waitfor(struct ast_channel *chan, int ms);
+
+/*! \brief Wait for a specified amount of time, looking for hangups
+ * \param chan channel to wait for
+ * \param ms length of time in milliseconds to sleep
+ * Waits for a specified amount of time, servicing the channel as required.
+ * \return returns -1 on hangup, otherwise 0.
+ */
+int ast_safe_sleep(struct ast_channel *chan, int ms);
+
+/*! \brief Wait for a specified amount of time, looking for hangups and a condition argument
+ * \param chan channel to wait for
+ * \param ms length of time in milliseconds to sleep
+ * \param cond a function pointer for testing continue condition
+ * \param data argument to be passed to the condition test function
+ * \return returns -1 on hangup, otherwise 0.
+ * Waits for a specified amount of time, servicing the channel as required. If cond
+ * returns 0, this function returns.
+ */
+int ast_safe_sleep_conditional(struct ast_channel *chan, int ms, int (*cond)(void*), void *data );
+
+/*! \brief Waits for activity on a group of channels
+ * \param chan an array of pointers to channels
+ * \param n number of channels that are to be waited upon
+ * \param fds an array of fds to wait upon
+ * \param nfds the number of fds to wait upon
+ * \param exception exception flag
+ * \param outfd fd that had activity on it
+ * \param ms how long the wait was
+ * Big momma function here. Wait for activity on any of the n channels, or any of the nfds
+ file descriptors.
+ \return Returns the channel with activity, or NULL on error or if an FD
+ came first. If the FD came first, it will be returned in outfd, otherwise, outfd
+ will be -1 */
+struct ast_channel *ast_waitfor_nandfds(struct ast_channel **chan, int n,
+ int *fds, int nfds, int *exception, int *outfd, int *ms);
+
+/*! \brief Waits for input on a group of channels
+ Wait for input on an array of channels for a given # of milliseconds.
+ \return Return channel with activity, or NULL if none has activity.
+ \param chan an array of pointers to channels
+ \param n number of channels that are to be waited upon
+ \param ms time "ms" is modified in-place, if applicable */
+struct ast_channel *ast_waitfor_n(struct ast_channel **chan, int n, int *ms);
+
+/*! \brief Waits for input on an fd
+ This version works on fd's only. Be careful with it. */
+int ast_waitfor_n_fd(int *fds, int n, int *ms, int *exception);
+
+
+/*! \brief Reads a frame
+ * \param chan channel to read a frame from
+ * \return Returns a frame, or NULL on error. If it returns NULL, you
+ best just stop reading frames and assume the channel has been
+ disconnected. */
+struct ast_frame *ast_read(struct ast_channel *chan);
+
+/*! \brief Reads a frame, returning AST_FRAME_NULL frame if audio.
+ \param chan channel to read a frame from
+ \return Returns a frame, or NULL on error. If it returns NULL, you
+ best just stop reading frames and assume the channel has been
+ disconnected.
+ \note Audio is replaced with AST_FRAME_NULL to avoid
+ transcode when the resulting audio is not necessary. */
+struct ast_frame *ast_read_noaudio(struct ast_channel *chan);
+
+/*! \brief Write a frame to a channel
+ * This function writes the given frame to the indicated channel.
+ * \param chan destination channel of the frame
+ * \param frame frame that will be written
+ * \return It returns 0 on success, -1 on failure.
+ */
+int ast_write(struct ast_channel *chan, struct ast_frame *frame);
+
+/*! \brief Write video frame to a channel
+ * This function writes the given frame to the indicated channel.
+ * \param chan destination channel of the frame
+ * \param frame frame that will be written
+ * \return It returns 1 on success, 0 if not implemented, and -1 on failure.
+ */
+int ast_write_video(struct ast_channel *chan, struct ast_frame *frame);
+
+/*! \brief Write text frame to a channel
+ * This function writes the given frame to the indicated channel.
+ * \param chan destination channel of the frame
+ * \param frame frame that will be written
+ * \return It returns 1 on success, 0 if not implemented, and -1 on failure.
+ */
+int ast_write_text(struct ast_channel *chan, struct ast_frame *frame);
+
+/*! \brief Send empty audio to prime a channel driver */
+int ast_prod(struct ast_channel *chan);
+
+/*! \brief Sets read format on channel chan
+ * Set read format for channel to whichever component of "format" is best.
+ * \param chan channel to change
+ * \param format format to change to
+ * \return Returns 0 on success, -1 on failure
+ */
+int ast_set_read_format(struct ast_channel *chan, int format);
+
+/*! \brief Sets write format on channel chan
+ * Set write format for channel to whichever component of "format" is best.
+ * \param chan channel to change
+ * \param format new format for writing
+ * \return Returns 0 on success, -1 on failure
+ */
+int ast_set_write_format(struct ast_channel *chan, int format);
+
+/*!
+ * \brief Sends text to a channel
+ *
+ * \param chan channel to act upon
+ * \param text string of text to send on the channel
+ *
+ * Write text to a display on a channel
+ *
+ * \note The channel does not need to be locked before calling this function.
+ *
+ * \retval 0 on success
+ * \retval -1 on failure
+ */
+int ast_sendtext(struct ast_channel *chan, const char *text);
+
+/*! \brief Receives a text character from a channel
+ * \param chan channel to act upon
+ * \param timeout timeout in milliseconds (0 for infinite wait)
+ * Read a char of text from a channel
+ * Returns 0 on success, -1 on failure
+ */
+int ast_recvchar(struct ast_channel *chan, int timeout);
+
+/*! \brief Send a DTMF digit to a channel
+ * Send a DTMF digit to a channel.
+ * \param chan channel to act upon
+ * \param digit the DTMF digit to send, encoded in ASCII
+ * \param duration the duration of the digit ending in ms
+ * \return Returns 0 on success, -1 on failure
+ */
+int ast_senddigit(struct ast_channel *chan, char digit, unsigned int duration);
+
+/*! \brief Send a DTMF digit to a channel
+ * Send a DTMF digit to a channel.
+ * \param chan channel to act upon
+ * \param digit the DTMF digit to send, encoded in ASCII
+ * \return Returns 0 on success, -1 on failure
+ */
+int ast_senddigit_begin(struct ast_channel *chan, char digit);
+
+/*! \brief Send a DTMF digit to a channel
+
+ * Send a DTMF digit to a channel.
+ * \param chan channel to act upon
+ * \param digit the DTMF digit to send, encoded in ASCII
+ * \param duration the duration of the digit ending in ms
+ * \return Returns 0 on success, -1 on failure
+ */
+int ast_senddigit_end(struct ast_channel *chan, char digit, unsigned int duration);
+
+/*! \brief Receives a text string from a channel
+ * Read a string of text from a channel
+ * \param chan channel to act upon
+ * \param timeout timeout in milliseconds (0 for infinite wait)
+ * \return the received text, or NULL to signify failure.
+ */
+char *ast_recvtext(struct ast_channel *chan, int timeout);
+
+/*! \brief Browse channels in use
+ * Browse the channels currently in use
+ * \param prev where you want to start in the channel list
+ * \return Returns the next channel in the list, NULL on end.
+ * If it returns a channel, that channel *has been locked*!
+ */
+struct ast_channel *ast_channel_walk_locked(const struct ast_channel *prev);
+
+/*! \brief Get channel by name or uniqueid (locks channel) */
+struct ast_channel *ast_get_channel_by_name_locked(const char *chan);
+
+/*! \brief Get channel by name or uniqueid prefix (locks channel) */
+struct ast_channel *ast_get_channel_by_name_prefix_locked(const char *name, const int namelen);
+
+/*! \brief Get channel by name or uniqueid prefix (locks channel) */
+struct ast_channel *ast_walk_channel_by_name_prefix_locked(const struct ast_channel *chan, const char *name, const int namelen);
+
+/*! \brief Get channel by exten (and optionally context) and lock it */
+struct ast_channel *ast_get_channel_by_exten_locked(const char *exten, const char *context);
+
+/*! \brief Get next channel by exten (and optionally context) and lock it */
+struct ast_channel *ast_walk_channel_by_exten_locked(const struct ast_channel *chan, const char *exten,
+ const char *context);
+
+/*! ! \brief Waits for a digit
+ * \param c channel to wait for a digit on
+ * \param ms how many milliseconds to wait
+ * \return Returns <0 on error, 0 on no entry, and the digit on success. */
+int ast_waitfordigit(struct ast_channel *c, int ms);
+
+/*! \brief Wait for a digit
+ Same as ast_waitfordigit() with audio fd for outputting read audio and ctrlfd to monitor for reading.
+ * \param c channel to wait for a digit on
+ * \param ms how many milliseconds to wait
+ * \param audiofd audio file descriptor to write to if audio frames are received
+ * \param ctrlfd control file descriptor to monitor for reading
+ * \return Returns 1 if ctrlfd becomes available */
+int ast_waitfordigit_full(struct ast_channel *c, int ms, int audiofd, int ctrlfd);
+
+/*! Reads multiple digits
+ * \param c channel to read from
+ * \param s string to read in to. Must be at least the size of your length
+ * \param len how many digits to read (maximum)
+ * \param timeout how long to timeout between digits
+ * \param rtimeout timeout to wait on the first digit
+ * \param enders digits to end the string
+ * Read in a digit string "s", max length "len", maximum timeout between
+ digits "timeout" (-1 for none), terminated by anything in "enders". Give them rtimeout
+ for the first digit. Returns 0 on normal return, or 1 on a timeout. In the case of
+ a timeout, any digits that were read before the timeout will still be available in s.
+ RETURNS 2 in full version when ctrlfd is available, NOT 1*/
+int ast_readstring(struct ast_channel *c, char *s, int len, int timeout, int rtimeout, char *enders);
+int ast_readstring_full(struct ast_channel *c, char *s, int len, int timeout, int rtimeout, char *enders, int audiofd, int ctrlfd);
+
+/*! \brief Report DTMF on channel 0 */
+#define AST_BRIDGE_DTMF_CHANNEL_0 (1 << 0)
+/*! \brief Report DTMF on channel 1 */
+#define AST_BRIDGE_DTMF_CHANNEL_1 (1 << 1)
+/*! \brief Return all voice frames on channel 0 */
+#define AST_BRIDGE_REC_CHANNEL_0 (1 << 2)
+/*! \brief Return all voice frames on channel 1 */
+#define AST_BRIDGE_REC_CHANNEL_1 (1 << 3)
+/*! \brief Ignore all signal frames except NULL */
+#define AST_BRIDGE_IGNORE_SIGS (1 << 4)
+
+
+/*! \brief Makes two channel formats compatible
+ * \param c0 first channel to make compatible
+ * \param c1 other channel to make compatible
+ * Set two channels to compatible formats -- call before ast_channel_bridge in general .
+ * \return Returns 0 on success and -1 if it could not be done */
+int ast_channel_make_compatible(struct ast_channel *c0, struct ast_channel *c1);
+
+/*! Bridge two channels together (early)
+ * \param c0 first channel to bridge
+ * \param c1 second channel to bridge
+ * Bridge two channels (c0 and c1) together early. This implies either side may not be answered yet.
+ * \return Returns 0 on success and -1 if it could not be done */
+int ast_channel_early_bridge(struct ast_channel *c0, struct ast_channel *c1);
+
+/*! Bridge two channels together
+ * \param c0 first channel to bridge
+ * \param c1 second channel to bridge
+ * \param config config for the channels
+ * \param fo destination frame(?)
+ * \param rc destination channel(?)
+ * Bridge two channels (c0 and c1) together. If an important frame occurs, we return that frame in
+ *rf (remember, it could be NULL) and which channel (0 or 1) in rc */
+/* int ast_channel_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc); */
+int ast_channel_bridge(struct ast_channel *c0,struct ast_channel *c1,
+ struct ast_bridge_config *config, struct ast_frame **fo, struct ast_channel **rc);
+
+/*!
+ * \brief Weird function made for call transfers
+ *
+ * \param original channel to make a copy of
+ * \param clone copy of the original channel
+ *
+ * This is a very strange and freaky function used primarily for transfer. Suppose that
+ * "original" and "clone" are two channels in random situations. This function takes
+ * the guts out of "clone" and puts them into the "original" channel, then alerts the
+ * channel driver of the change, asking it to fixup any private information (like the
+ * p->owner pointer) that is affected by the change. The physical layer of the original
+ * channel is hung up.
+ *
+ * \note Neither channel passed here needs to be locked before calling this function.
+ */
+int ast_channel_masquerade(struct ast_channel *original, struct ast_channel *clone);
+
+/*! Gives the string form of a given cause code */
+/*!
+ * \param state cause to get the description of
+ * Give a name to a cause code
+ * Returns the text form of the binary cause code given
+ */
+const char *ast_cause2str(int state) attribute_pure;
+
+/*! Convert the string form of a cause code to a number */
+/*!
+ * \param name string form of the cause
+ * Returns the cause code
+ */
+int ast_str2cause(const char *name) attribute_pure;
+
+/*! Gives the string form of a given channel state */
+/*!
+ * \param ast_channel_state state to get the name of
+ * Give a name to a state
+ * Returns the text form of the binary state given
+ */
+const char *ast_state2str(enum ast_channel_state);
+
+/*! Gives the string form of a given transfer capability */
+/*!
+ * \param transfercapability transfercapabilty to get the name of
+ * Give a name to a transfercapbility
+ * See above
+ * Returns the text form of the binary transfer capability
+ */
+char *ast_transfercapability2str(int transfercapability) attribute_const;
+
+/* Options: Some low-level drivers may implement "options" allowing fine tuning of the
+ low level channel. See frame.h for options. Note that many channel drivers may support
+ none or a subset of those features, and you should not count on this if you want your
+ asterisk application to be portable. They're mainly useful for tweaking performance */
+
+/*! Sets an option on a channel */
+/*!
+ * \param channel channel to set options on
+ * \param option option to change
+ * \param data data specific to option
+ * \param datalen length of the data
+ * \param block blocking or not
+ * Set an option on a channel (see frame.h), optionally blocking awaiting the reply
+ * Returns 0 on success and -1 on failure
+ */
+int ast_channel_setoption(struct ast_channel *channel, int option, void *data, int datalen, int block);
+
+/*! Pick the best codec */
+/* Choose the best codec... Uhhh... Yah. */
+int ast_best_codec(int fmts);
+
+
+/*! Checks the value of an option */
+/*!
+ * Query the value of an option, optionally blocking until a reply is received
+ * Works similarly to setoption except only reads the options.
+ */
+struct ast_frame *ast_channel_queryoption(struct ast_channel *channel, int option, void *data, int *datalen, int block);
+
+/*! Checks for HTML support on a channel */
+/*! Returns 0 if channel does not support HTML or non-zero if it does */
+int ast_channel_supports_html(struct ast_channel *channel);
+
+/*! Sends HTML on given channel */
+/*! Send HTML or URL on link. Returns 0 on success or -1 on failure */
+int ast_channel_sendhtml(struct ast_channel *channel, int subclass, const char *data, int datalen);
+
+/*! Sends a URL on a given link */
+/*! Send URL on link. Returns 0 on success or -1 on failure */
+int ast_channel_sendurl(struct ast_channel *channel, const char *url);
+
+/*! Defers DTMF */
+/*! Defer DTMF so that you only read things like hangups and audio. Returns
+ non-zero if channel was already DTMF-deferred or 0 if channel is just now
+ being DTMF-deferred */
+int ast_channel_defer_dtmf(struct ast_channel *chan);
+
+/*! Undo defer. ast_read will return any dtmf characters that were queued */
+void ast_channel_undefer_dtmf(struct ast_channel *chan);
+
+/*! Initiate system shutdown -- prevents new channels from being allocated.
+ If "hangup" is non-zero, all existing channels will receive soft
+ hangups */
+void ast_begin_shutdown(int hangup);
+
+/*! Cancels an existing shutdown and returns to normal operation */
+void ast_cancel_shutdown(void);
+
+/*! Returns number of active/allocated channels */
+int ast_active_channels(void);
+
+/*! Returns non-zero if Asterisk is being shut down */
+int ast_shutting_down(void);
+
+/*! Activate a given generator */
+int ast_activate_generator(struct ast_channel *chan, struct ast_generator *gen, void *params);
+
+/*! Deactivate an active generator */
+void ast_deactivate_generator(struct ast_channel *chan);
+
+/*!
+ * \brief Set caller ID number, name and ANI
+ *
+ * \note The channel does not need to be locked before calling this function.
+ */
+void ast_set_callerid(struct ast_channel *chan, const char *cid_num, const char *cid_name, const char *cid_ani);
+
+/*! Set the file descriptor on the channel */
+void ast_channel_set_fd(struct ast_channel *chan, int which, int fd);
+
+/*! Add a channel to an optimized waitfor */
+void ast_poll_channel_add(struct ast_channel *chan0, struct ast_channel *chan1);
+
+/*! Delete a channel from an optimized waitfor */
+void ast_poll_channel_del(struct ast_channel *chan0, struct ast_channel *chan1);
+
+/*! Start a tone going */
+int ast_tonepair_start(struct ast_channel *chan, int freq1, int freq2, int duration, int vol);
+/*! Stop a tone from playing */
+void ast_tonepair_stop(struct ast_channel *chan);
+/*! Play a tone pair for a given amount of time */
+int ast_tonepair(struct ast_channel *chan, int freq1, int freq2, int duration, int vol);
+
+/*!
+ * \brief Automatically service a channel for us...
+ *
+ * \retval 0 success
+ * \retval -1 failure, or the channel is already being autoserviced
+ */
+int ast_autoservice_start(struct ast_channel *chan);
+
+/*!
+ * \brief Stop servicing a channel for us...
+ *
+ * \retval 0 success
+ * \retval -1 error, or the channel has been hungup
+ */
+int ast_autoservice_stop(struct ast_channel *chan);
+
+/* If built with zaptel optimizations, force a scheduled expiration on the
+ timer fd, at which point we call the callback function / data */
+int ast_settimeout(struct ast_channel *c, int samples, int (*func)(const void *data), void *data);
+
+/*! \brief Transfer a channel (if supported). Returns -1 on error, 0 if not supported
+ and 1 if supported and requested
+ \param chan current channel
+ \param dest destination extension for transfer
+*/
+int ast_transfer(struct ast_channel *chan, char *dest);
+
+/*! \brief Start masquerading a channel
+ XXX This is a seriously whacked out operation. We're essentially putting the guts of
+ the clone channel into the original channel. Start by killing off the original
+ channel's backend. I'm not sure we're going to keep this function, because
+ while the features are nice, the cost is very high in terms of pure nastiness. XXX
+ \param chan Channel to masquerade
+*/
+int ast_do_masquerade(struct ast_channel *chan);
+
+/*! \brief Find bridged channel
+ \param chan Current channel
+*/
+struct ast_channel *ast_bridged_channel(struct ast_channel *chan);
+
+/*!
+ \brief Inherits channel variable from parent to child channel
+ \param parent Parent channel
+ \param child Child channel
+
+ Scans all channel variables in the parent channel, looking for those
+ that should be copied into the child channel.
+ Variables whose names begin with a single '_' are copied into the
+ child channel with the prefix removed.
+ Variables whose names begin with '__' are copied into the child
+ channel with their names unchanged.
+*/
+void ast_channel_inherit_variables(const struct ast_channel *parent, struct ast_channel *child);
+
+/*!
+ \brief adds a list of channel variables to a channel
+ \param chan the channel
+ \param vars a linked list of variables
+
+ Variable names can be for a regular channel variable or a dialplan function
+ that has the ability to be written to.
+*/
+void ast_set_variables(struct ast_channel *chan, struct ast_variable *vars);
+
+/*!
+ \brief An opaque 'object' structure use by silence generators on channels.
+ */
+struct ast_silence_generator;
+
+/*!
+ \brief Starts a silence generator on the given channel.
+ \param chan The channel to generate silence on
+ \return An ast_silence_generator pointer, or NULL if an error occurs
+
+ This function will cause SLINEAR silence to be generated on the supplied
+ channel until it is disabled; if the channel cannot be put into SLINEAR
+ mode then the function will fail.
+
+ The pointer returned by this function must be preserved and passed to
+ ast_channel_stop_silence_generator when you wish to stop the silence
+ generation.
+ */
+struct ast_silence_generator *ast_channel_start_silence_generator(struct ast_channel *chan);
+
+/*!
+ \brief Stops a previously-started silence generator on the given channel.
+ \param chan The channel to operate on
+ \param state The ast_silence_generator pointer return by a previous call to
+ ast_channel_start_silence_generator.
+ \return nothing
+
+ This function will stop the operating silence generator and return the channel
+ to its previous write format.
+ */
+void ast_channel_stop_silence_generator(struct ast_channel *chan, struct ast_silence_generator *state);
+
+/*!
+ \brief Check if the channel can run in internal timing mode.
+ \param chan The channel to check
+ \return boolean
+
+ This function will return 1 if internal timing is enabled and the timing
+ device is available.
+ */
+int ast_internal_timing_enabled(struct ast_channel *chan);
+
+/* Misc. functions below */
+
+/*! \brief if fd is a valid descriptor, set *pfd with the descriptor
+ * \return Return 1 (not -1!) if added, 0 otherwise (so we can add the
+ * return value to the index into the array)
+ */
+static inline int ast_add_fd(struct pollfd *pfd, int fd)
+{
+ pfd->fd = fd;
+ pfd->events = POLLIN | POLLPRI;
+ return fd >= 0;
+}
+
+/*! \brief Helper function for migrating select to poll */
+static inline int ast_fdisset(struct pollfd *pfds, int fd, int max, int *start)
+{
+ int x;
+ int dummy=0;
+
+ if (fd < 0)
+ return 0;
+ if (!start)
+ start = &dummy;
+ for (x = *start; x<max; x++)
+ if (pfds[x].fd == fd) {
+ if (x == *start)
+ (*start)++;
+ return pfds[x].revents;
+ }
+ return 0;
+}
+
+#ifndef HAVE_TIMERSUB
+static inline void timersub(struct timeval *tvend, struct timeval *tvstart, struct timeval *tvdiff)
+{
+ tvdiff->tv_sec = tvend->tv_sec - tvstart->tv_sec;
+ tvdiff->tv_usec = tvend->tv_usec - tvstart->tv_usec;
+ if (tvdiff->tv_usec < 0) {
+ tvdiff->tv_sec --;
+ tvdiff->tv_usec += 1000000;
+ }
+
+}
+#endif
+
+/*! \brief Waits for activity on a group of channels
+ * \param nfds the maximum number of file descriptors in the sets
+ * \param rfds file descriptors to check for read availability
+ * \param wfds file descriptors to check for write availability
+ * \param efds file descriptors to check for exceptions (OOB data)
+ * \param tvp timeout while waiting for events
+ * This is the same as a standard select(), except it guarantees the
+ * behaviour where the passed struct timeval is updated with how much
+ * time was not slept while waiting for the specified events
+ */
+static inline int ast_select(int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *tvp)
+{
+#ifdef __linux__
+ return select(nfds, rfds, wfds, efds, tvp);
+#else
+ if (tvp) {
+ struct timeval tv, tvstart, tvend, tvlen;
+ int res;
+
+ tv = *tvp;
+ gettimeofday(&tvstart, NULL);
+ res = select(nfds, rfds, wfds, efds, tvp);
+ gettimeofday(&tvend, NULL);
+ timersub(&tvend, &tvstart, &tvlen);
+ timersub(&tv, &tvlen, tvp);
+ if (tvp->tv_sec < 0 || (tvp->tv_sec == 0 && tvp->tv_usec < 0)) {
+ tvp->tv_sec = 0;
+ tvp->tv_usec = 0;
+ }
+ return res;
+ }
+ else
+ return select(nfds, rfds, wfds, efds, NULL);
+#endif
+}
+
+#ifdef DO_CRASH
+#define CRASH do { fprintf(stderr, "!! Forcing immediate crash a-la abort !!\n"); *((int *)0) = 0; } while(0)
+#else
+#define CRASH do { } while(0)
+#endif
+
+#define CHECK_BLOCKING(c) do { \
+ if (ast_test_flag(c, AST_FLAG_BLOCKING)) {\
+ if (option_debug) \
+ ast_log(LOG_DEBUG, "Thread %ld Blocking '%s', already blocked by thread %ld in procedure %s\n", (long) pthread_self(), (c)->name, (long) (c)->blocker, (c)->blockproc); \
+ CRASH; \
+ } else { \
+ (c)->blocker = pthread_self(); \
+ (c)->blockproc = __PRETTY_FUNCTION__; \
+ ast_set_flag(c, AST_FLAG_BLOCKING); \
+ } } while (0)
+
+ast_group_t ast_get_group(const char *s);
+
+/*! \brief print call- and pickup groups into buffer */
+char *ast_print_group(char *buf, int buflen, ast_group_t group);
+
+/*! \brief Convert enum channelreloadreason to text string for manager event
+ \param reason Enum channelreloadreason - reason for reload (manager, cli, start etc)
+*/
+const char *channelreloadreason2txt(enum channelreloadreason reason);
+
+/*! \brief return an ast_variable list of channeltypes */
+struct ast_variable *ast_channeltype_list(void);
+
+/*!
+ \brief return an english explanation of the code returned thru __ast_request_and_dial's 'outstate' argument
+ \param reason The integer argument, usually taken from AST_CONTROL_ macros
+ \return char pointer explaining the code
+ */
+const char *ast_channel_reason2str(int reason);
+
+/*! \brief channel group info
+ */
+struct ast_group_info {
+ struct ast_channel *chan;
+ char *category;
+ char *group;
+ AST_LIST_ENTRY(ast_group_info) list;
+};
+
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _ASTERISK_CHANNEL_H */
diff --git a/trunk/include/asterisk/chanvars.h b/trunk/include/asterisk/chanvars.h
new file mode 100644
index 000000000..63de58429
--- /dev/null
+++ b/trunk/include/asterisk/chanvars.h
@@ -0,0 +1,42 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2005, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief Channel Variables
+ */
+
+#ifndef _ASTERISK_CHANVARS_H
+#define _ASTERISK_CHANVARS_H
+
+#include "asterisk/linkedlists.h"
+
+struct ast_var_t {
+ AST_LIST_ENTRY(ast_var_t) entries;
+ char *value;
+ char name[0];
+};
+
+AST_LIST_HEAD_NOLOCK(varshead, ast_var_t);
+
+struct ast_var_t *ast_var_assign(const char *name, const char *value);
+void ast_var_delete(struct ast_var_t *var);
+const char *ast_var_name(const struct ast_var_t *var);
+const char *ast_var_full_name(const struct ast_var_t *var);
+const char *ast_var_value(const struct ast_var_t *var);
+
+#endif /* _ASTERISK_CHANVARS_H */
diff --git a/trunk/include/asterisk/cli.h b/trunk/include/asterisk/cli.h
new file mode 100644
index 000000000..854c189ff
--- /dev/null
+++ b/trunk/include/asterisk/cli.h
@@ -0,0 +1,285 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2005, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief Standard Command Line Interface
+ */
+
+#ifndef _ASTERISK_CLI_H
+#define _ASTERISK_CLI_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+#include "asterisk/linkedlists.h"
+
+void ast_cli(int fd, const char *fmt, ...)
+ __attribute__ ((format (printf, 2, 3)));
+
+#define RESULT_SUCCESS 0
+#define RESULT_SHOWUSAGE 1
+#define RESULT_FAILURE 2
+
+#define CLI_SUCCESS (char *)RESULT_SUCCESS
+#define CLI_SHOWUSAGE (char *)RESULT_SHOWUSAGE
+#define CLI_FAILURE (char *)RESULT_FAILURE
+
+#define AST_MAX_CMD_LEN 16
+
+#define AST_MAX_ARGS 64
+
+#define AST_CLI_COMPLETE_EOF "_EOF_"
+
+/*!
+ * In many cases we need to print singular or plural
+ * words depending on a count. This macro helps us e.g.
+ * printf("we have %d object%s", n, ESS(n));
+ */
+#define ESS(x) ((x) == 1 ? "" : "s")
+
+/*! \page CLI_command_API CLI command API
+
+ CLI commands are described by a struct ast_cli_entry that contains
+ all the components for their implementation.
+
+ In the "old-style" format, the record must contain:
+ - a NULL-terminated array of words constituting the command, e.g.
+ { "set", "debug", "on", NULL },
+ - a summary string (short) and a usage string (longer);
+ - a handler which implements the command itself, invoked with
+ a file descriptor and argc/argv as typed by the user
+ - a 'generator' function which, given a partial string, can
+ generate legal completions for it.
+ An example is
+
+ int old_setdebug(int fd, int argc, char *argv[]);
+ char *dbg_complete(const char *line, const char *word, int pos, int n);
+
+ { { "set", "debug", "on", NULL }, do_setdebug, "Enable debugging",
+ set_debug_usage, dbg_complete },
+
+ In the "new-style" format, all the above functionalities are implemented
+ by a single function, and the arguments tell which output is required.
+ The prototype is the following:
+
+ char *new_setdebug(const struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
+
+ ...
+ // this is how we create the entry to register
+ AST_CLI_DEFINE(new_setdebug, "short description")
+ ...
+
+ To help the transition, we make the pointer to the struct ast_cli_entry
+ available to old-style handlers via argv[-1].
+
+ An example of new-style handler is the following
+
+\code
+static char *test_new_cli(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+{
+ static char *choices = { "one", "two", "three", NULL };
+
+ switch (cmd) {
+ case CLI_INIT:
+ e->command = "do this well";
+ e->usage =
+ "Usage: do this well <arg>\n"
+ " typically multiline with body indented\n";
+ return NULL;
+
+ case CLI_GENERATE:
+ if (a->pos > e->args)
+ return NULL;
+ return ast_cli_complete(a->word, choices, a->n);
+
+ default:
+ // we are guaranteed to be called with argc >= e->args;
+ if (a->argc > e->args + 1) // we accept one extra argument
+ return CLI_SHOWUSAGE;
+ ast_cli(a->fd, "done this well for %s\n", e->args[argc-1]);
+ return CLI_SUCCESS;
+ }
+}
+
+\endcode
+
+ */
+
+/*! \brief calling arguments for new-style handlers.
+* \arg \ref CLI_command_API
+*/
+enum ast_cli_fn {
+ CLI_INIT = -2, /* return the usage string */
+ CLI_GENERATE = -3, /* behave as 'generator', remap argv to struct ast_cli_args */
+ CLI_HANDLER = -4, /* run the normal handler */
+};
+
+/* argument for new-style CLI handler */
+struct ast_cli_args {
+ int fd;
+ int argc;
+ char **argv;
+ const char *line; /* the current input line */
+ const char *word; /* the word we want to complete */
+ int pos; /* position of the word to complete */
+ int n; /* the iteration count (n-th entry we generate) */
+};
+
+struct ast_cli_entry;
+typedef char *(*cli_fn)(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
+
+/*! \brief descriptor for a cli entry.
+ * \arg \ref CLI_command_API
+ */
+struct ast_cli_entry {
+ char * const cmda[AST_MAX_CMD_LEN]; /*!< words making up the command.
+ * set the first entry to NULL for a new-style entry. */
+
+ const char *summary; /*!< Summary of the command (< 60 characters) */
+ const char *usage; /*!< Detailed usage information */
+
+ struct ast_cli_entry *deprecate_cmd;
+
+ int inuse; /*!< For keeping track of usage */
+ struct module *module; /*!< module this belongs to */
+ char *_full_cmd; /*!< built at load time from cmda[] */
+ int cmdlen; /*!< len up to the first invalid char [<{% */
+ /*! \brief This gets set in ast_cli_register()
+ It then gets set to something different when the deprecated command
+ is run for the first time (ie; after we warn the user that it's deprecated)
+ */
+ int args; /*!< number of non-null entries in cmda */
+ char *command; /*!< command, non-null for new-style entries */
+ int deprecated;
+ cli_fn handler;
+ char *_deprecated_by; /*!< copied from the "parent" _full_cmd, on deprecated commands */
+ /*! For linking */
+ AST_LIST_ENTRY(ast_cli_entry) list;
+};
+
+/* XXX the parser in gcc 2.95 gets confused if you don't put a space
+ * between the last arg before VA_ARGS and the comma */
+#define AST_CLI_DEFINE(fn, txt , ... ) { .handler = fn, .summary = txt, ## __VA_ARGS__ }
+
+/*!
+ * Helper function to generate cli entries from a NULL-terminated array.
+ * Returns the n-th matching entry from the array, or NULL if not found.
+ * Can be used to implement generate() for static entries as below
+ * (in this example we complete the word in position 2):
+ \code
+ char *my_generate(const char *line, const char *word, int pos, int n)
+ {
+ static char *choices = { "one", "two", "three", NULL };
+ if (pos == 2)
+ return ast_cli_complete(word, choices, n);
+ else
+ return NULL;
+ }
+ \endcode
+ */
+char *ast_cli_complete(const char *word, char *const choices[], int pos);
+
+/*!
+ * \brief Interprets a command
+ * Interpret a command s, sending output to fd
+ * \param fd pipe
+ * \param s incoming string
+ * \retval 0 on success
+ * \retval -1 on failure
+ */
+int ast_cli_command(int fd, const char *s);
+
+/*!
+ * \brief Executes multiple CLI commands
+ * Interpret strings separated by NULL and execute each one, sending output to fd
+ * \param fd pipe
+ * \param size is the total size of the string
+ * \param s incoming string
+ * \retval number of commands executed
+ */
+int ast_cli_command_multiple(int fd, size_t size, const char *s);
+
+/*! \brief Registers a command or an array of commands
+ * \param e which cli entry to register.
+ * Register your own command
+ * \retval 0 on success
+ * \retval -1 on failure
+ */
+int ast_cli_register(struct ast_cli_entry *e);
+
+/*!
+ * \brief Register multiple commands
+ * \param e pointer to first cli entry to register
+ * \param len number of entries to register
+ */
+int ast_cli_register_multiple(struct ast_cli_entry *e, int len);
+
+/*!
+ * \brief Unregisters a command or an array of commands
+ * \param e which cli entry to unregister
+ * Unregister your own command. You must pass a completed ast_cli_entry structure
+ * \return 0
+ */
+int ast_cli_unregister(struct ast_cli_entry *e);
+
+/*!
+ * \brief Unregister multiple commands
+ * \param e pointer to first cli entry to unregister
+ * \param len number of entries to unregister
+ */
+int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len);
+
+/*!
+ * \brief Readline madness
+ * Useful for readline, that's about it
+ * \retval 0 on success
+ * \retval -1 on failure
+ */
+char *ast_cli_generator(const char *, const char *, int);
+
+int ast_cli_generatornummatches(const char *, const char *);
+
+/*!
+ * \brief Generates a NULL-terminated array of strings that
+ * 1) begin with the string in the second parameter, and
+ * 2) are valid in a command after the string in the first parameter.
+ *
+ * The first entry (offset 0) of the result is the longest common substring
+ * in the results, useful to extend the string that has been completed.
+ * Subsequent entries are all possible values, followed by a NULL.
+ * All strings and the array itself are malloc'ed and must be freed
+ * by the caller.
+ */
+char **ast_cli_completion_matches(const char *, const char *);
+
+/*!
+ * \brief Command completion for the list of active channels.
+ *
+ * This can be called from a CLI command completion function that wants to
+ * complete from the list of active channels. 'rpos' is the required
+ * position in the command. This function will return NULL immediately if
+ * 'rpos' is not the same as the current position, 'pos'.
+ */
+char *ast_complete_channels(const char *line, const char *word, int pos, int state, int rpos);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _ASTERISK_CLI_H */
diff --git a/trunk/include/asterisk/compat.h b/trunk/include/asterisk/compat.h
new file mode 100644
index 000000000..43da49bc0
--- /dev/null
+++ b/trunk/include/asterisk/compat.h
@@ -0,0 +1,184 @@
+/*
+ * Asterisk -- A telephony toolkit for Linux.
+ *
+ * Copyright (C) 1999-2006, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License
+ */
+
+/*! \file
+ * \brief General Definitions for Asterisk top level program
+ * Included by asterisk.h to handle platform-specific issues
+ * especially those related to header files.
+ */
+
+#include "asterisk/compiler.h"
+
+#ifndef _COMPAT_H
+#define _COMPAT_H
+
+#ifndef __STDC_VERSION__
+/* flex output wants to find this defined. */
+#define __STDC_VERSION__ 0
+#endif
+
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifdef HAVE_STDDEF_H
+#include <stddef.h>
+#endif
+
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#include <stdarg.h>
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#ifdef HAVE_ALLOCA_H
+#include <alloca.h> /* not necessarily present - could be in stdlib */
+#elif defined(HAVE_ALLOCA) && defined(__MINGW32__)
+#include <malloc.h> /* see if it is here... */
+#endif
+
+#include <stdio.h> /* this is always present */
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#ifdef HAVE_SYS_POLL_H
+#include <sys/poll.h>
+#else
+#include "asterisk/poll-compat.h"
+#endif
+
+#if !defined(HAVE_ASPRINTF) && !defined(__AST_DEBUG_MALLOC)
+int asprintf(char **str, const char *fmt, ...);
+#endif
+
+#ifndef HAVE_GETLOADAVG
+int getloadavg(double *list, int nelem);
+#endif
+
+#ifndef HAVE_SETENV
+int setenv(const char *name, const char *value, int overwrite);
+#endif
+
+#ifndef HAVE_STRCASESTR
+char *strcasestr(const char *, const char *);
+#endif
+
+#if !defined(HAVE_STRNDUP) && !defined(__AST_DEBUG_MALLOC)
+char *strndup(const char *, size_t);
+#endif
+
+#ifndef HAVE_STRNLEN
+size_t strnlen(const char *, size_t);
+#endif
+
+#ifndef HAVE_STRSEP
+char* strsep(char** str, const char* delims);
+#endif
+
+#ifndef HAVE_STRTOQ
+uint64_t strtoq(const char *nptr, char **endptr, int base);
+#endif
+
+#ifndef HAVE_UNSETENV
+int unsetenv(const char *name);
+#endif
+
+#if !defined(HAVE_VASPRINTF) && !defined(__AST_DEBUG_MALLOC)
+int vasprintf(char **strp, const char *fmt, va_list ap);
+#endif
+
+#ifndef HAVE_STRLCAT
+size_t strlcat(char *dst, const char *src, size_t siz);
+#endif
+
+#ifndef HAVE_STRLCPY
+size_t strlcpy(char *dst, const char *src, size_t siz);
+#endif
+
+#include <errno.h>
+
+#ifdef SOLARIS
+#define __BEGIN_DECLS
+#define __END_DECLS
+
+#ifndef __P
+#define __P(p) p
+#endif
+
+#include <alloca.h>
+#include <strings.h>
+#include <string.h>
+#include <pthread.h>
+#include <sys/stat.h>
+#include <signal.h>
+#include <netinet/in.h>
+#include <sys/loadavg.h>
+#include <dat/dat_platform_specific.h>
+
+#ifndef BYTE_ORDER
+#define LITTLE_ENDIAN 1234
+#define BIG_ENDIAN 4321
+
+#ifdef __sparc__
+#define BYTE_ORDER BIG_ENDIAN
+#else
+#define BYTE_ORDER LITTLE_ENDIAN
+#endif
+#endif
+
+#ifndef __BYTE_ORDER
+#define __LITTLE_ENDIAN LITTLE_ENDIAN
+#define __BIG_ENDIAN BIG_ENDIAN
+#define __BYTE_ORDER BYTE_ORDER
+#endif
+
+#ifndef __BIT_TYPES_DEFINED__
+#define __BIT_TYPES_DEFINED__
+typedef unsigned char u_int8_t;
+typedef unsigned short u_int16_t;
+typedef unsigned int u_int32_t;
+#endif
+
+#endif /* SOLARIS */
+
+#ifdef __CYGWIN__
+#define _WIN32_WINNT 0x0500
+#ifndef INET_ADDRSTRLEN
+#define INET_ADDRSTRLEN 16
+#endif
+#ifndef INET6_ADDRSTRLEN
+#define INET6_ADDRSTRLEN 46
+#endif
+#endif /* __CYGWIN__ */
+
+#ifdef __CYGWIN__
+typedef unsigned long long uint64_t;
+#endif
+
+#endif
diff --git a/trunk/include/asterisk/compiler.h b/trunk/include/asterisk/compiler.h
new file mode 100644
index 000000000..8ac441463
--- /dev/null
+++ b/trunk/include/asterisk/compiler.h
@@ -0,0 +1,56 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2005, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief Compiler-specific macros and other items
+ */
+
+#ifndef _ASTERISK_COMPILER_H
+#define _ASTERISK_COMPILER_H
+
+#if HAVE_ATTRIBUTE_always_inline
+#define force_inline __attribute__((always_inline)) inline
+#else
+#define force_inline inline
+#endif
+
+#if HAVE_ATTRIBUTE_pure
+#define attribute_pure __attribute__((pure))
+#else
+#define attribute_pure
+#endif
+
+#if HAVE_ATTRIBUTE_const
+#define attribute_const __attribute__((const))
+#else
+#define attribute_const
+#endif
+
+#if HAVE_ATTRIBUTE_unused
+#define attribute_unused __attribute__((unused))
+#else
+#define attribute_unused
+#endif
+
+#if HAVE_ATTRIBUTE_malloc
+#define attribute_malloc __attribute__((malloc))
+#else
+#define attribute_malloc
+#endif
+
+#endif /* _ASTERISK_COMPILER_H */
diff --git a/trunk/include/asterisk/config.h b/trunk/include/asterisk/config.h
new file mode 100644
index 000000000..fe9d49d30
--- /dev/null
+++ b/trunk/include/asterisk/config.h
@@ -0,0 +1,406 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2005, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief Configuration File Parser
+ */
+
+#ifndef _ASTERISK_CONFIG_H
+#define _ASTERISK_CONFIG_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+#include "asterisk/utils.h"
+
+struct ast_config;
+
+struct ast_category;
+
+/*! Options for ast_config_load()
+ */
+enum {
+ /*! Load the configuration, including comments */
+ CONFIG_FLAG_WITHCOMMENTS = (1 << 0),
+ /*! On a reload, give us a -1 if the file hasn't changed. */
+ CONFIG_FLAG_FILEUNCHANGED = (1 << 1),
+ /*! Don't attempt to cache mtime on this config file. */
+ CONFIG_FLAG_NOCACHE = (1 << 2),
+};
+
+#define CONFIG_STATUS_FILEUNCHANGED (void *)-1
+
+/*! \brief Structure for variables, used for configurations and for channel variables
+*/
+struct ast_variable {
+ const char *name;
+ const char *value;
+ struct ast_variable *next;
+
+ char *file;
+
+ int lineno;
+ int object; /*!< 0 for variable, 1 for object */
+ int blanklines; /*!< Number of blanklines following entry */
+ struct ast_comment *precomments;
+ struct ast_comment *sameline;
+ struct ast_comment *trailing; /*!< the last object in the list will get assigned any trailing comments when EOF is hit */
+ char stuff[0];
+};
+
+typedef struct ast_config *config_load_func(const char *database, const char *table, const char *configfile, struct ast_config *config, struct ast_flags flags, const char *suggested_include_file);
+typedef struct ast_variable *realtime_var_get(const char *database, const char *table, va_list ap);
+typedef struct ast_config *realtime_multi_get(const char *database, const char *table, va_list ap);
+typedef int realtime_update(const char *database, const char *table, const char *keyfield, const char *entity, va_list ap);
+typedef int realtime_store(const char *database, const char *table, va_list ap);
+typedef int realtime_destroy(const char *database, const char *table, const char *keyfield, const char *entity, va_list ap);
+
+/*! \brief Configuration engine structure, used to define realtime drivers */
+struct ast_config_engine {
+ char *name;
+ config_load_func *load_func;
+ realtime_var_get *realtime_func;
+ realtime_multi_get *realtime_multi_func;
+ realtime_update *update_func;
+ realtime_store *store_func;
+ realtime_destroy *destroy_func;
+ struct ast_config_engine *next;
+};
+
+/*! \brief Load a config file
+ * \param filename path of file to open. If no preceding '/' character, path is considered relative to AST_CONFIG_DIR
+ * Create a config structure from a given configuration file.
+ * \param flags Optional flags:
+ * CONFIG_FLAG_WITHCOMMENTS - load the file with comments intact;
+ * CONFIG_FLAG_FILEUNCHANGED - check the file mtime and return CONFIG_STATUS_FILEUNCHANGED if the mtime is the same; or
+ * CONFIG_FLAG_NOCACHE - don't cache file mtime (main purpose of this option is to save memory on temporary files).
+ *
+ * \retval an ast_config data structure on success
+ * \retval NULL on error
+ */
+struct ast_config *ast_config_load(const char *filename, struct ast_flags flags);
+
+/*! \brief Destroys a config
+ * \param config pointer to config data structure
+ * Free memory associated with a given config
+ *
+ */
+void ast_config_destroy(struct ast_config *config);
+
+/*! \brief returns the root ast_variable of a config
+ * \param config pointer to an ast_config data structure
+ * \param cat name of the category for which you want the root
+ *
+ * Returns the category specified
+ */
+struct ast_variable *ast_category_root(struct ast_config *config, char *cat);
+
+/*! \brief Goes through categories
+ * \param config Which config structure you wish to "browse"
+ * \param prev A pointer to a previous category.
+ * This function is kind of non-intuitive in it's use. To begin, one passes NULL as the second argument. It will return a pointer to the string of the first category in the file. From here on after, one must then pass the previous usage's return value as the second pointer, and it will return a pointer to the category name afterwards.
+ *
+ * \retval a category on success
+ * \retval NULL on failure/no-more-categories
+ */
+char *ast_category_browse(struct ast_config *config, const char *prev);
+
+/*!
+ * \brief Goes through variables
+ * Somewhat similar in intent as the ast_category_browse.
+ * List variables of config file category
+ *
+ * \retval ast_variable list on success
+ * \retval NULL on failure
+ */
+struct ast_variable *ast_variable_browse(const struct ast_config *config, const char *category);
+
+/*!
+ * \brief given a pointer to a category, return the root variable.
+ * This is equivalent to ast_variable_browse(), but more efficient if we
+ * already have the struct ast_category * (e.g. from ast_category_get())
+ */
+struct ast_variable *ast_category_first(struct ast_category *cat);
+
+/*!
+ * \brief Gets a variable
+ * \param config which (opened) config to use
+ * \param category category under which the variable lies
+ * \param variable which variable you wish to get the data for
+ * Goes through a given config file in the given category and searches for the given variable
+ *
+ * \retval The variable value on success
+ * \retval NULL if unable to find it.
+ */
+const char *ast_variable_retrieve(const struct ast_config *config, const char *category, const char *variable);
+
+/*!
+ * \brief Retrieve a category if it exists
+ * \param config which config to use
+ * \param category_name name of the category you're looking for
+ * This will search through the categories within a given config file for a match.
+ *
+ * \retval pointer to category if found
+ * \retval NULL if not.
+ */
+struct ast_category *ast_category_get(const struct ast_config *config, const char *category_name);
+
+/*!
+ * \brief Check for category duplicates
+ * \param config which config to use
+ * \param category_name name of the category you're looking for
+ * This will search through the categories within a given config file for a match.
+ *
+ * \return non-zero if found
+ */
+int ast_category_exist(const struct ast_config *config, const char *category_name);
+
+/*!
+ * \brief Retrieve realtime configuration
+ * \param family which family/config to lookup
+ * This will use builtin configuration backends to look up a particular
+ * entity in realtime and return a variable list of its parameters. Note
+ * that unlike the variables in ast_config, the resulting list of variables
+ * MUST be freed with ast_variables_destroy() as there is no container.
+ */
+struct ast_variable *ast_load_realtime(const char *family, ...);
+struct ast_variable *ast_load_realtime_all(const char *family, ...);
+
+/*!
+ * \brief Retrieve realtime configuration
+ * \param family which family/config to lookup
+ * This will use builtin configuration backends to look up a particular
+ * entity in realtime and return a variable list of its parameters. Unlike
+ * the ast_load_realtime, this function can return more than one entry and
+ * is thus stored inside a taditional ast_config structure rather than
+ * just returning a linked list of variables.
+ */
+struct ast_config *ast_load_realtime_multientry(const char *family, ...);
+
+/*!
+ * \brief Update realtime configuration
+ * \param family which family/config to be updated
+ * \param keyfield which field to use as the key
+ * \param lookup which value to look for in the key field to match the entry.
+ * This function is used to update a parameter in realtime configuration space.
+ *
+ */
+int ast_update_realtime(const char *family, const char *keyfield, const char *lookup, ...);
+
+/*!
+ * \brief Create realtime configuration
+ * \param family which family/config to be created
+ * This function is used to create a parameter in realtime configuration space.
+ *
+ */
+int ast_store_realtime(const char *family, ...);
+
+/*!
+ * \brief Destroy realtime configuration
+ * \param family which family/config to be destroyed
+ * \param keyfield which field to use as the key
+ * \param lookup which value to look for in the key field to match the entry.
+ * This function is used to destroy an entry in realtime configuration space.
+ * Additional params are used as keys.
+ *
+ */
+int ast_destroy_realtime(const char *family, const char *keyfield, const char *lookup, ...);
+
+/*!
+ * \brief Check if realtime engine is configured for family
+ * \param family which family/config to be checked
+ * \return 1 if family is configured in realtime and engine exists
+*/
+int ast_check_realtime(const char *family);
+
+/*! \brief Check if there's any realtime engines loaded */
+int ast_realtime_enabled(void);
+
+/*! \brief Free variable list
+ * \param var the linked list of variables to free
+ * This function frees a list of variables.
+ */
+void ast_variables_destroy(struct ast_variable *var);
+
+/*! \brief Register config engine */
+int ast_config_engine_register(struct ast_config_engine *newconfig);
+
+/*! \brief Deegister config engine */
+int ast_config_engine_deregister(struct ast_config_engine *del);
+
+int register_config_cli(void);
+int read_config_maps(void);
+
+struct ast_config *ast_config_new(void);
+struct ast_category *ast_config_get_current_category(const struct ast_config *cfg);
+void ast_config_set_current_category(struct ast_config *cfg, const struct ast_category *cat);
+const char *ast_config_option(struct ast_config *cfg, const char *cat, const char *var);
+
+struct ast_category *ast_category_new(const char *name, const char *in_file, int lineno);
+void ast_category_append(struct ast_config *config, struct ast_category *cat);
+int ast_category_delete(struct ast_config *cfg, const char *category);
+void ast_category_destroy(struct ast_category *cat);
+struct ast_variable *ast_category_detach_variables(struct ast_category *cat);
+void ast_category_rename(struct ast_category *cat, const char *name);
+
+struct ast_variable *ast_variable_new(const char *name, const char *value, const char *filename);
+struct ast_config_include *ast_include_new(struct ast_config *conf, const char *from_file, const char *included_file, int is_exec, const char *exec_file, int from_lineno, char *real_included_file_name, int real_included_file_name_size);
+struct ast_config_include *ast_include_find(struct ast_config *conf, const char *included_file);
+void ast_include_rename(struct ast_config *conf, const char *from_file, const char *to_file);
+void ast_variable_append(struct ast_category *category, struct ast_variable *variable);
+int ast_variable_delete(struct ast_category *category, const char *variable, const char *match);
+int ast_variable_update(struct ast_category *category, const char *variable,
+ const char *value, const char *match, unsigned int object);
+
+int config_text_file_save(const char *filename, const struct ast_config *cfg, const char *generator);
+
+struct ast_config *ast_config_internal_load(const char *configfile, struct ast_config *cfg, struct ast_flags flags, const char *suggested_incl_file);
+
+/*! \brief Support code to parse config file arguments
+ *
+ * The function ast_parse_arg() provides a generic interface to parse
+ * strings (e.g. numbers, network addresses and so on) in a flexible
+ * way, e.g. by doing proper error and bound checks, provide default
+ * values, and so on.
+ * The function (described later) takes a string as an argument,
+ * a set of flags to specify the result format and checks to perform,
+ * a pointer to the result, and optionally some additional arguments.
+ * It returns 0 on success, != 0 otherwise.
+ *
+ */
+enum ast_parse_flags {
+ /* low 4 bits of flags are used for the operand type */
+ PARSE_TYPE = 0x000f,
+ /* numeric types, with optional default value and bound checks.
+ * Additional arguments are passed by value.
+ */
+ PARSE_INT32 = 0x0001,
+ PARSE_UINT32 = 0x0002,
+ PARSE_DOUBLE = 0x0003,
+#if 0 /* not supported yet */
+ PARSE_INT16 = 0x0004,
+ PARSE_UINT16 = 0x0005,
+#endif
+ /* Returns a struct sockaddr_in, with optional default value
+ * (passed by reference) and port handling (accept, ignore,
+ * require, forbid). The format is 'host.name[:port]'
+ */
+ PARSE_INADDR = 0x000f,
+
+ /* Other data types can be added as needed */
+
+ /* If PARSE_DEFAULT is set, next argument is a default value
+ * which is returned in case of error. The argument is passed
+ * by value in case of numeric types, by reference in other cases.
+ */
+ PARSE_DEFAULT = 0x0010, /* assign default on error */
+
+ /* Request a range check, applicable to numbers. Two additional
+ * arguments are passed by value, specifying the low-high end of
+ * the range (inclusive). An error is returned if the value
+ * is outside or inside the range, respectively.
+ */
+ PARSE_IN_RANGE = 0x0020, /* accept values inside a range */
+ PARSE_OUT_RANGE = 0x0040, /* accept values outside a range */
+
+ /* Port handling, for sockaddr_in. accept/ignore/require/forbid
+ * port number after the hostname or address.
+ */
+ PARSE_PORT_MASK = 0x0300, /* 0x000: accept port if present */
+ PARSE_PORT_IGNORE = 0x0100, /* 0x100: ignore port if present */
+ PARSE_PORT_REQUIRE = 0x0200, /* 0x200: require port number */
+ PARSE_PORT_FORBID = 0x0300, /* 0x100: forbid port number */
+};
+
+/*! \brief The argument parsing routine.
+ * \param arg the string to parse. It is not modified.
+ * \param flags combination of ast_parse_flags to specify the
+ * return type and additional checks.
+ * \param result pointer to the result. NULL is valid here, and can
+ * be used to perform only the validity checks.
+ * \param ... extra arguments are required according to flags.
+ * \retval 0 in case of success, != 0 otherwise.
+ * \retval result returns the parsed value in case of success,
+ * the default value in case of error, or it is left unchanged
+ * in case of error and no default specified. Note that in certain
+ * cases (e.g. sockaddr_in, with multi-field return values) some
+ * of the fields in result may be changed even if an error occurs.
+ *
+ * Examples of use:
+ * ast_parse_arg("223", PARSE_INT32|PARSE_IN_RANGE,
+ * &a, -1000, 1000);
+ * returns 0, a = 223
+ * ast_parse_arg("22345", PARSE_INT32|PARSE_IN_RANGE|PARSE_DEFAULT,
+ * &a, 9999, 10, 100);
+ * returns 1, a = 9999
+ * ast_parse_arg("22345ssf", PARSE_UINT32|PARSE_IN_RANGE, &b, 10, 100);
+ * returns 1, b unchanged
+ * ast_parse_arg("www.foo.biz:44", PARSE_INADDR, &sa);
+ * returns 0, sa contains address and port
+ * ast_parse_arg("www.foo.biz", PARSE_INADDR|PARSE_PORT_REQUIRE, &sa);
+ * returns 1 because port is missing, sa contains address
+ */
+int ast_parse_arg(const char *arg, enum ast_parse_flags flags,
+ void *result, ...);
+
+/*
+ * Parsing config file options in C is slightly annoying because we cannot use
+ * string in a switch() statement, yet we need a similar behaviour, with many
+ * branches and a break on a matching one.
+ * The following somehow simplifies the job: we create a block using
+ * the CV_START and CV_END macros, and then within the block we can run
+ * actions such as "if (condition) { body; break; }"
+ * Additional macros are present to run simple functions (e.g. ast_copy_string)
+ * or to pass arguments to ast_parse_arg()
+ *
+ * As an example:
+
+ CV_START(v->name, v->value); // start the block
+ CV_STR("foo", x_foo); // static string
+ CV_DSTR("bar", y_bar); // malloc'ed string
+ CV_F("bar", ...); // call a generic function
+ CV_END; // end the block
+ */
+
+/*! \brief the macro to open a block for variable parsing */
+#define CV_START(__in_var, __in_val) \
+ do { \
+ const char *__var = __in_var; \
+ const char *__val = __in_val;
+
+/*! \brief close a variable parsing block */
+#define CV_END } while (0)
+
+/*! \brief call a generic function if the name matches. */
+#define CV_F(__pattern, __body) if (!strcasecmp((__var), __pattern)) { __body; break; }
+
+/*! \brief helper macros to assign the value to a BOOL, UINT, static string and
+ * dynamic string
+ */
+#define CV_BOOL(__x, __dst) CV_F(__x, (__dst) = ast_true(__val) )
+#define CV_UINT(__x, __dst) CV_F(__x, (__dst) = strtoul(__val, NULL, 0) )
+#define CV_STR(__x, __dst) CV_F(__x, ast_copy_string(__dst, __val, sizeof(__dst)))
+#define CV_DSTR(__x, __dst) CV_F(__x, if (__dst) ast_free(__dst); __dst = ast_strdup(__val))
+#define CV_STRFIELD(__x, __obj, __field) CV_F(__x, ast_string_field_set(__obj, __field, __val))
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _ASTERISK_CONFIG_H */
diff --git a/trunk/include/asterisk/crypto.h b/trunk/include/asterisk/crypto.h
new file mode 100644
index 000000000..427c5ea51
--- /dev/null
+++ b/trunk/include/asterisk/crypto.h
@@ -0,0 +1,126 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2005, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief Provide cryptographic signature routines
+ */
+
+#ifndef _ASTERISK_CRYPTO_H
+#define _ASTERISK_CRYPTO_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+#define AST_KEY_PUBLIC (1 << 0)
+#define AST_KEY_PRIVATE (1 << 1)
+
+struct ast_key;
+
+/*!
+ * \brief Retrieve a key
+ * \param name of the key we are retrieving
+ * \param int type of key (AST_KEY_PUBLIC or AST_KEY_PRIVATE)
+ *
+ * \retval the key on success.
+ * \retval NULL on failure.
+ */
+struct ast_key *(*ast_key_get)(const char *key, int type);
+
+/*!
+ * \brief Check the authenticity of a message signature using a given public key
+ * \param key a public key to use to verify
+ * \param msg the message that has been signed
+ * \param sig the proposed valid signature in mime64-like encoding
+ *
+ * \retval 0 if the signature is valid.
+ * \retval -1 otherwise.
+ *
+ */
+int (*ast_check_signature)(struct ast_key *key, const char *msg, const char *sig);
+
+/*!
+ * \brief Check the authenticity of a message signature using a given public key
+ * \param key a public key to use to verify
+ * \param msg the message that has been signed
+ * \param sig the proposed valid signature in raw binary representation
+ *
+ * \retval 0 if the signature is valid.
+ * \retval -1 otherwise.
+ *
+ */
+int (*ast_check_signature_bin)(struct ast_key *key, const char *msg, int msglen, const unsigned char *sig);
+
+/*!
+ * \brief Sign a message signature using a given private key
+ * \param key a private key to use to create the signature
+ * \param msg the message to sign
+ * \param sig a pointer to a buffer of at least 256 bytes in which the
+ * mime64-like encoded signature will be stored
+ *
+ * \retval 0 on success.
+ * \retval -1 on failure.
+ *
+ */
+int (*ast_sign)(struct ast_key *key, char *msg, char *sig);
+
+/*!
+ * \brief Sign a message signature using a given private key
+ * \param key a private key to use to create the signature
+ * \param msg the message to sign
+ * \param sig a pointer to a buffer of at least 128 bytes in which the
+ * raw encoded signature will be stored
+ *
+ * \retval 0 on success.
+ * \retval -1 on failure.
+ *
+ */
+int (*ast_sign_bin)(struct ast_key *key, const char *msg, int msglen, unsigned char *sig);
+
+/*!
+ * \brief Encrypt a message using a given private key
+ * \param key a private key to use to encrypt
+ * \param src the message to encrypt
+ * \param srclen the length of the message to encrypt
+ * \param dst a pointer to a buffer of at least srclen * 1.5 bytes in which the encrypted
+ * answer will be stored
+ *
+ * \retval length of encrypted data on success.
+ * \retval -1 on failure.
+ *
+ */
+int (*ast_encrypt_bin)(unsigned char *dst, const unsigned char *src, int srclen, struct ast_key *key);
+
+/*!
+ * \brief Decrypt a message using a given private key
+ * \param key a private key to use to decrypt
+ * \param src the message to decrypt
+ * \param srclen the length of the message to decrypt
+ * \param dst a pointer to a buffer of at least srclen bytes in which the decrypted
+ * answer will be stored
+ *
+ * \retval length of dencrypted data on success.
+ * \retval -1 on failure.
+ *
+ */
+int (*ast_decrypt_bin)(unsigned char *dst, const unsigned char *src, int srclen, struct ast_key *key);
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _ASTERISK_CRYPTO_H */
diff --git a/trunk/include/asterisk/devicestate.h b/trunk/include/asterisk/devicestate.h
new file mode 100644
index 000000000..d52430301
--- /dev/null
+++ b/trunk/include/asterisk/devicestate.h
@@ -0,0 +1,203 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2005, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief Device state management
+ *
+ * To subscribe to device state changes, use the generic ast_event_subscribe
+ * method. For an example, see apps/app_queue.c.
+ *
+ * \todo Currently, when the state of a device changes, the device state provider
+ * calls one of the functions defined here to queue an object to say that the
+ * state of a device has changed. However, this does not include the new state.
+ * Another thread processes these device state change objects and calls the
+ * device state provider's callback to figure out what the new state is. It
+ * would make a lot more sense for the new state to be included in the original
+ * function call that says the state of a device has changed. However, it
+ * will take a lot of work to change this.
+ *
+ * \arg See \ref AstExtState
+ */
+
+#ifndef _ASTERISK_DEVICESTATE_H
+#define _ASTERISK_DEVICESTATE_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/*! \brief Device States
+ * \note The order of these states may not change because they are included
+ * in Asterisk events which may be transmitted across the network to
+ * other servers.
+ */
+enum ast_device_state {
+ AST_DEVICE_UNKNOWN, /*!< Device is valid but channel didn't know state */
+ AST_DEVICE_NOT_INUSE, /*!< Device is not used */
+ AST_DEVICE_INUSE, /*!< Device is in use */
+ AST_DEVICE_BUSY, /*!< Device is busy */
+ AST_DEVICE_INVALID, /*!< Device is invalid */
+ AST_DEVICE_UNAVAILABLE, /*!< Device is unavailable */
+ AST_DEVICE_RINGING, /*!< Device is ringing */
+ AST_DEVICE_RINGINUSE, /*!< Device is ringing *and* in use */
+ AST_DEVICE_ONHOLD, /*!< Device is on hold */
+};
+
+/*! \brief Devicestate provider call back */
+typedef enum ast_device_state (*ast_devstate_prov_cb_type)(const char *data);
+
+/*!
+ * \brief Convert device state to text string for output
+ *
+ * \param devstate Current device state
+ */
+const char *devstate2str(enum ast_device_state devstate);
+
+/*!
+ * \brief Convert device state to text string that is easier to parse
+ *
+ * \param devstate Current device state
+ */
+const char *ast_devstate_str(enum ast_device_state devstate);
+
+/*!
+ * \brief Convert device state from text to integer value
+ *
+ * \param val The text representing the device state. Valid values are anything
+ * that comes after AST_DEVICE_ in one of the defined values.
+ *
+ * \return The AST_DEVICE_ integer value
+ */
+enum ast_device_state ast_devstate_val(const char *val);
+
+/*!
+ * \brief Search the Channels by Name
+ *
+ * \param device like a dial string
+ *
+ * Search the Device in active channels by compare the channel name against
+ * the device name. Compared are only the first chars to the first '-' char.
+ *
+ * \retval AST_DEVICE_UNKNOWN if no channel found
+ * \retval AST_DEVICE_INUSE if a channel is found
+ */
+enum ast_device_state ast_parse_device_state(const char *device);
+
+/*!
+ * \brief Asks a channel for device state
+ *
+ * \param device like a dial string
+ *
+ * Asks a channel for device state, data is normally a number from a dial string
+ * used by the low level module
+ * Tries the channel device state callback if not supported search in the
+ * active channels list for the device.
+ *
+ * \retval an AST_DEVICE_??? state
+ * \retval -1 on failure
+ */
+enum ast_device_state ast_device_state(const char *device);
+
+/*!
+ * \brief Tells Asterisk the State for Device is changed
+ *
+ * \param state the new state of the device
+ * \param fmt device name like a dial string with format parameters
+ *
+ * The new state of the device will be sent off to any subscribers
+ * of device states. It will also be stored in the internal event
+ * cache.
+ *
+ * \retval 0 on success
+ * \retval -1 on failure
+ */
+int ast_devstate_changed(enum ast_device_state state, const char *fmt, ...)
+ __attribute__ ((format (printf, 2, 3)));
+
+/*!
+ * \brief Tells Asterisk the State for Device is changed
+ *
+ * \param state the new state of the device
+ * \param device device name like a dial string with format parameters
+ *
+ * The new state of the device will be sent off to any subscribers
+ * of device states. It will also be stored in the internal event
+ * cache.
+ *
+ * \retval 0 on success
+ * \retval -1 on failure
+ */
+int ast_devstate_changed_literal(enum ast_device_state state, const char *device);
+
+/*!
+ * \brief Tells Asterisk the State for Device is changed
+ *
+ * \param fmt device name like a dial string with format parameters
+ *
+ * Asterisk polls the new extension states and calls the registered
+ * callbacks for the changed extensions
+ *
+ * \retval 0 on success
+ * \retval -1 on failure
+ *
+ * \note This is deprecated in favor of ast_devstate_changed()
+ */
+int ast_device_state_changed(const char *fmt, ...)
+ __attribute__ ((format (printf, 1, 2)));
+
+/*!
+ * \brief Tells Asterisk the State for Device is changed
+ *
+ * \param device device name like a dial string
+ *
+ * Asterisk polls the new extension states and calls the registered
+ * callbacks for the changed extensions
+ *
+ * \retval 0 on success
+ * \retval -1 on failure
+ *
+ * \note This is deprecated in favor of ast_devstate_changed_literal()
+ */
+int ast_device_state_changed_literal(const char *device);
+
+/*!
+ * \brief Add device state provider
+ *
+ * \param label to use in hint, like label:object
+ * \param callback Callback
+ *
+ * \retval 0 success
+ * \retval -1 failure
+ */
+int ast_devstate_prov_add(const char *label, ast_devstate_prov_cb_type callback);
+
+/*!
+ * \brief Remove device state provider
+ *
+ * \param label to use in hint, like label:object
+ *
+ * \retval -1 on failure
+ * \retval 0 on success
+ */
+int ast_devstate_prov_del(const char *label);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _ASTERISK_DEVICESTATE_H */
diff --git a/trunk/include/asterisk/dial.h b/trunk/include/asterisk/dial.h
new file mode 100644
index 000000000..9a2478070
--- /dev/null
+++ b/trunk/include/asterisk/dial.h
@@ -0,0 +1,168 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2007, Digium, Inc.
+ *
+ * Joshua Colp <jcolp@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief Dialing API
+ */
+
+#ifndef _ASTERISK_DIAL_H
+#define _ASTERISK_DIAL_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/*! \brief Main dialing structure. Contains global options, channels being dialed, and more! */
+struct ast_dial;
+
+/*! \brief Dialing channel structure. Contains per-channel dialing options, asterisk channel, and more! */
+struct ast_dial_channel;
+
+typedef void (*ast_dial_state_callback)(struct ast_dial *);
+
+/*! \brief List of options that are applicable either globally or per dialed channel */
+enum ast_dial_option {
+ AST_DIAL_OPTION_RINGING, /*!< Always indicate ringing to caller */
+ AST_DIAL_OPTION_ANSWER_EXEC, /*!< Execute application upon answer in async mode */
+ AST_DIAL_OPTION_MUSIC, /*!< Play music on hold instead of ringing to the calling channel */
+ AST_DIAL_OPTION_DISABLE_CALL_FORWARDING, /*!< Disable call forwarding on channels */
+ AST_DIAL_OPTION_MAX, /*!< End terminator -- must always remain last */
+};
+
+/*! \brief List of return codes for dial run API calls */
+enum ast_dial_result {
+ AST_DIAL_RESULT_INVALID, /*!< Invalid options were passed to run function */
+ AST_DIAL_RESULT_FAILED, /*!< Attempts to dial failed before reaching critical state */
+ AST_DIAL_RESULT_TRYING, /*!< Currently trying to dial */
+ AST_DIAL_RESULT_RINGING, /*!< Dial is presently ringing */
+ AST_DIAL_RESULT_PROGRESS, /*!< Dial is presently progressing */
+ AST_DIAL_RESULT_PROCEEDING, /*!< Dial is presently proceeding */
+ AST_DIAL_RESULT_ANSWERED, /*!< A channel was answered */
+ AST_DIAL_RESULT_TIMEOUT, /*!< Timeout was tripped, nobody answered */
+ AST_DIAL_RESULT_HANGUP, /*!< Caller hung up */
+ AST_DIAL_RESULT_UNANSWERED, /*!< Nobody answered */
+};
+
+/*! \brief New dialing structure
+ * \note Create a dialing structure
+ * \return Returns a calloc'd ast_dial structure, NULL on failure
+ */
+struct ast_dial *ast_dial_create(void);
+
+/*! \brief Append a channel
+ * \note Appends a channel to a dialing structure
+ * \return Returns channel reference number on success, -1 on failure
+ */
+int ast_dial_append(struct ast_dial *dial, const char *tech, const char *device);
+
+/*! \brief Execute dialing synchronously or asynchronously
+ * \note Dials channels in a dial structure.
+ * \return Returns dial result code. (TRYING/INVALID/FAILED/ANSWERED/TIMEOUT/UNANSWERED).
+ */
+enum ast_dial_result ast_dial_run(struct ast_dial *dial, struct ast_channel *chan, int async);
+
+/*! \brief Return channel that answered
+ * \note Returns the Asterisk channel that answered
+ * \param dial Dialing structure
+ */
+struct ast_channel *ast_dial_answered(struct ast_dial *dial);
+
+/*! \brief Return state of dial
+ * \note Returns the state of the dial attempt
+ * \param dial Dialing structure
+ */
+enum ast_dial_result ast_dial_state(struct ast_dial *dial);
+
+/*! \brief Cancel async thread
+ * \note Cancel a running async thread
+ * \param dial Dialing structure
+ */
+enum ast_dial_result ast_dial_join(struct ast_dial *dial);
+
+/*! \brief Hangup channels
+ * \note Hangup all active channels
+ * \param dial Dialing structure
+ */
+void ast_dial_hangup(struct ast_dial *dial);
+
+/*! \brief Destroys a dialing structure
+ * \note Cancels dialing and destroys (free's) the given ast_dial structure
+ * \param dial Dialing structure to free
+ * \return Returns 0 on success, -1 on failure
+ */
+int ast_dial_destroy(struct ast_dial *dial);
+
+/*! \brief Enables an option globally
+ * \param dial Dial structure to enable option on
+ * \param option Option to enable
+ * \param data Data to pass to this option (not always needed)
+ * \return Returns 0 on success, -1 on failure
+ */
+int ast_dial_option_global_enable(struct ast_dial *dial, enum ast_dial_option option, void *data);
+
+/*! \brief Enables an option per channel
+ * \param dial Dial structure
+ * \param num Channel number to enable option on
+ * \param option Option to enable
+ * \param data Data to pass to this option (not always needed)
+ * \return Returns 0 on success, -1 on failure
+ */
+int ast_dial_option_enable(struct ast_dial *dial, int num, enum ast_dial_option option, void *data);
+
+/*! \brief Disables an option globally
+ * \param dial Dial structure to disable option on
+ * \param option Option to disable
+ * \return Returns 0 on success, -1 on failure
+ */
+int ast_dial_option_global_disable(struct ast_dial *dial, enum ast_dial_option option);
+
+/*! \brief Disables an option per channel
+ * \param dial Dial structure
+ * \param num Channel number to disable option on
+ * \param option Option to disable
+ * \return Returns 0 on success, -1 on failure
+ */
+int ast_dial_option_disable(struct ast_dial *dial, int num, enum ast_dial_option option);
+
+/*! \brief Set a callback for state changes
+ * \param dial The dial structure to watch for state changes
+ * \param callback the callback
+ * \return nothing
+ */
+void ast_dial_set_state_callback(struct ast_dial *dial, ast_dial_state_callback callback);
+
+/*! \brief Set the maximum time (globally) allowed for trying to ring phones
+ * \param dial The dial structure to apply the time limit to
+ * \param timeout Maximum time allowed
+ * \return nothing
+ */
+void ast_dial_set_global_timeout(struct ast_dial *dial, int timeout);
+
+/*! \brief Set the maximum time (per channel) allowed for trying to ring the phone
+ * \param dial The dial structure the channel belongs to
+ * \param num Channel number to set timeout on
+ * \param timeout Maximum time allowed
+ * \return nothing
+ */
+void ast_dial_set_timeout(struct ast_dial *dial, int num, int timeout);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _ASTERISK_DIAL_H */
diff --git a/trunk/include/asterisk/dlfcn-compat.h b/trunk/include/asterisk/dlfcn-compat.h
new file mode 100644
index 000000000..2ce827a6a
--- /dev/null
+++ b/trunk/include/asterisk/dlfcn-compat.h
@@ -0,0 +1,88 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ */
+
+/*
+Copyright (c) 2002 Jorge Acereda <jacereda@users.sourceforge.net> &
+ Peter O'Gorman <ogorman@users.sourceforge.net>
+
+Portions may be copyright others, see the AUTHORS file included with this
+distribution.
+
+Maintained by Peter O'Gorman <ogorman@users.sourceforge.net>
+
+Bug Reports and other queries should go to <ogorman@users.sourceforge.net>
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef _DLFCN_H_
+#define _DLFCN_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined (__GNUC__) && __GNUC__ > 3
+#define dl_restrict __restrict
+#else
+#define dl_restrict
+#endif
+/*
+ * Structure filled in by dladdr().
+ */
+
+typedef struct dl_info {
+ const char *dli_fname; /* Pathname of shared object */
+ void *dli_fbase; /* Base address of shared object */
+ const char *dli_sname; /* Name of nearest symbol */
+ void *dli_saddr; /* Address of nearest symbol */
+} Dl_info;
+
+extern void * dlopen(const char *path, int mode);
+extern void * dlsym(void * dl_restrict handle, const char * dl_restrict symbol);
+extern const char * dlerror(void);
+extern int dlclose(void * handle);
+extern int dladdr(const void * dl_restrict, Dl_info * dl_restrict);
+
+#define RTLD_LAZY 0x1
+#define RTLD_NOW 0x2
+#define RTLD_LOCAL 0x4
+#define RTLD_GLOBAL 0x8
+#define RTLD_NOLOAD 0x10
+#define RTLD_NODELETE 0x80
+
+/*
+ * Special handle arguments for dlsym().
+ */
+#define RTLD_NEXT ((void *) -1) /* Search subsequent objects. */
+#define RTLD_DEFAULT ((void *) -2) /* Use default search algorithm. */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _DLFCN_H_ */
diff --git a/trunk/include/asterisk/dns.h b/trunk/include/asterisk/dns.h
new file mode 100644
index 000000000..64cf68c10
--- /dev/null
+++ b/trunk/include/asterisk/dns.h
@@ -0,0 +1,39 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Written by Thorsten Lockert <tholo@trollphone.org>
+ *
+ * Funding provided by Troll Phone Networks AS
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief DNS support for Asterisk
+ * \author Thorsten Lockert <tholo@trollphone.org>
+ */
+
+#ifndef _ASTERISK_DNS_H
+#define _ASTERISK_DNS_H
+
+/*! \brief Perform DNS lookup (used by DNS, enum and SRV lookups)
+ \param context
+ \param dname Domain name to lookup (host, SRV domain, TXT record name)
+ \param class Record Class (see "man res_search")
+ \param type Record type (see "man res_search")
+ \param callback Callback function for handling DNS result
+ \note Asterisk DNS is synchronus at this time. This means that if your DNS
+ services does not work, Asterisk may lock while waiting for response.
+*/
+int ast_search_dns(void *context, const char *dname, int class, int type,
+ int (*callback)(void *context, unsigned char *answer, int len, unsigned char *fullanswer));
+
+#endif /* _ASTERISK_DNS_H */
diff --git a/trunk/include/asterisk/dnsmgr.h b/trunk/include/asterisk/dnsmgr.h
new file mode 100644
index 000000000..33b9556e7
--- /dev/null
+++ b/trunk/include/asterisk/dnsmgr.h
@@ -0,0 +1,62 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2005, Digium, Inc.
+ *
+ * Kevin P. Fleming <kpfleming@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief Background DNS update manager
+ */
+
+#ifndef _ASTERISK_DNSMGR_H
+#define _ASTERISK_DNSMGR_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+#include "asterisk/network.h"
+
+struct ast_dnsmgr_entry;
+
+struct ast_dnsmgr_entry *ast_dnsmgr_get(const char *name, struct in_addr *result);
+
+void ast_dnsmgr_release(struct ast_dnsmgr_entry *entry);
+
+int ast_dnsmgr_lookup(const char *name, struct in_addr *result, struct ast_dnsmgr_entry **dnsmgr);
+
+/*!
+ * \brief Force a refresh of a dnsmgr entry
+ *
+ * \retval non-zero if the result is different than the previous result
+ * \retval zero if the result is the same as the previous result
+ */
+int ast_dnsmgr_refresh(struct ast_dnsmgr_entry *entry);
+
+/*!
+ * \brief Check is see if a dnsmgr entry has changed
+ *
+ * \retval non-zero if the dnsmgr entry has changed since the last call to
+ * this function
+ * \retval zero if the dnsmgr entry has not changed since the last call to
+ * this function
+ */
+int ast_dnsmgr_changed(struct ast_dnsmgr_entry *entry);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif /* c_plusplus */
+
+#endif /* ASTERISK_DNSMGR_H */
diff --git a/trunk/include/asterisk/doxyref.h b/trunk/include/asterisk/doxyref.h
new file mode 100644
index 000000000..6fbe462ec
--- /dev/null
+++ b/trunk/include/asterisk/doxyref.h
@@ -0,0 +1,563 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2005, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief This file generates Doxygen pages from files in the /doc
+ directory of the Asterisk source code tree
+ */
+
+/* The following is for Doxygen Developer's documentation generated
+ * by running "make progdocs" with doxygen installed on your
+ * system.
+ */
+/*! \page DevDoc Asterisk Developer's Documentation - appendices
+ * \arg \ref CodeGuide : The must-read document for all developer's
+ * \arg \ref AstAPI
+ * \arg \ref Def_Channel : What's a channel, anyway?
+ * \arg \ref channel_drivers : Existing channel drivers
+ * \arg \ref AstDebug : Hints on debugging
+ * \arg \ref AstAMI : The Call management socket API
+ * \arg \ref AstARA : A generic data storage and retrieval API for Asterisk
+ * \arg \ref AstDUNDi : A way to find phone services dynamically by using the DUNDi protocol
+ * \arg \ref AJI_intro : The Asterisk Jabber Interface
+ * \arg \ref AstCDR
+ * \arg \ref AstREADME
+ * \arg \ref AstVar
+ * \arg \ref AstVideo
+ * \arg \ref AstENUM : The IETF way to redirect from phone numbers to VoIP calls
+ * \arg \ref AstHTTP
+ * \arg \ref AstSpeech
+ * \arg \ref ConfigFiles
+ * \arg \ref SoundFiles included in the Asterisk distribution
+ * \arg \ref AstCREDITS : A Thank You to contributors
+ * \arg \ref extref
+ \n\n
+ * \section weblinks Web sites
+ * \arg \b Main: Asterisk Developer's website http://www.asterisk.org/developers/
+ * \arg \b Bugs: The Issue tracker http://bugs.digium.com
+ * \arg \b Lists: List server http://lists.digium.com
+ * \arg \b Wiki: The Asterisk Wiki http://www.voip-info.org
+ * \arg \b Docs: The Asterisk Documentation Project http://www.asteriskdocs.org
+ * \arg \b Digium: The Asterisk company http://www.digium.com
+ *
+ */
+
+/*! \page CodeGuide Coding Guidelines
+ * \section Coding Guidelines
+ * This file is in the /doc directory in your Asterisk source tree.
+ * Make sure to stay up to date with the latest guidelines.
+ * \verbinclude CODING-GUIDELINES
+ */
+
+/*! \page AstAPI Asterisk API
+ * \section Asteriskapi Asterisk API
+ * Some generic documents on the Asterisk architecture
+ *
+ * \arg \ref AstThreadStorage
+ * \arg \ref DataStores
+ * \arg \ref AstExtState
+ *
+ * \subsection model_txt Generic Model
+ * \verbinclude model.txt
+ * \subsection channel_txt Channels
+ * \arg See \ref Def_Channel
+ */
+
+/*! \page AstDebug Debugging
+ * \section debug Debugging
+ * \verbinclude backtrace.txt
+ */
+
+/*! \page AstSpeech The Generic Speech Recognition API
+ * \section debug The Generic Speech Recognition API
+ * \verbinclude speechrec.txt
+ */
+
+/*! \page DataStores Channel Data Stores
+ * \section debug Channel Data Stores
+ * \verbinclude datastores.txt
+ */
+
+/*! \page AstAMI AMI - The Manager Interface
+ * \section ami AMI - The manager Interface
+ * \arg \link Config_ami Configuration file \endlink
+ * \arg \ref manager.c
+ * \verbinclude manager.txt
+ */
+
+/*! \page AstARA ARA - The Asterisk Realtime Interface
+ * \section realtime ARA - a generic API to storage and retrieval
+ * Implemented in \ref config.c
+ * Implemented in \ref pbx_realtime.c
+ * \verbinclude realtime.txt
+ * \verbinclude extconfig.txt
+ */
+
+/*! \page AstDUNDi DUNDi
+DUNDi is a peer-to-peer system for locating Internet gateways to telephony services. Unlike traditional centralized services (such as the remarkably simple and concise ENUM standard), DUNDi is fully-distributed with no centralized authority whatsoever.
+
+DUNDi is not itself a Voice-over IP signaling or media protocol. Instead, it publishes routes which are in turn accessed via industry standard protocols such as IAX, SIP and H.323.
+
+ \par References
+ \arg DUNDi is documented at http://www.dundi.com
+ \arg Implemented in \ref pbx_dundi.c and \ref dundi-parser.c
+ \arg Configuration in \link Config_dun dundi.conf \endlink
+ */
+
+/*! \page AstCDR CDR - Call Data Records and billing
+ * \section cdr Call Data Records
+ * \par See also
+ * \arg \ref cdr.c
+ * \arg \ref cdr_drivers
+ * \arg \ref Config_cdr CDR configuration files
+ *
+ * \verbinclude cdrdriver.txt
+ */
+
+/*! \page AstREADME README - the general administrator introduction
+ * \verbinclude README
+ */
+
+/*! \page AstCREDITS CREDITS
+ * \verbinclude CREDITS
+ */
+
+/*! \page AstVideo Video support in Asterisk
+ * \section sectAstVideo Video support in Asterisk
+ * \verbinclude video.txt
+ */
+
+/*! \page AstVar Globally predefined channel variables
+ * \section globchan Globally predefined channel variables
+ *
+ * More and more of these variables are being replaced by dialplan functions.
+ * Some still exist though and some that does still exist needs to move to
+ * dialplan functions.
+ *
+ * See also
+ * - \ref pbx_retrieve_variable()
+ * - \ref AstChanVar
+ *
+ * \verbinclude channelvariables.txt
+
+ */
+
+/*! \page AstChanVar Asterisk Dialplan Variables
+ * Asterisk Dialplan variables are divided into three groups:
+ * - Predefined global variables, handled by the PBX core
+ * - Global variables, that exist for the duration of the pbx execution
+ * - Channel variables, that exist during a channel
+ *
+ * Global variables are reachable in all channels, all of the time.
+ * Channel variables are only reachable within the channel.
+ *
+ * For more information on the predefined variables, see \ref AstVar
+ *
+ * Global and Channel variables:
+ * - Names are Case insensitive
+ * - Names that start with a character, but are alphanumeric
+ * - Global variables are defined and reached with the GLOBAL() dialplan function
+ * and the set application, like
+ *
+ * exten => 1234,1,set(GLOBAL(myvariable)=tomteluva)
+ *
+ * - \ref func_global.c
+ *
+ * - Channel variables are defined with the set() dialplan application
+ *
+ * exten => 1234,1,set(xmasattribute=tomtegröt)
+ *
+ * - Some channels also supports setting channel variables with the \b setvar=
+ * configuraiton option for a device or line.
+ *
+ * \section AstChanVar_globalvars Global Variables
+ * Global variables can also be set in the [globals] section of extensions.conf. The
+ * setting \b clearglobalvars in extensions.conf [general] section affects whether
+ * or not the global variables defined in \b globals are reset at dialplan reload.
+ *
+ * There are CLI commands to change and read global variables. This can be handy
+ * to reset counters at midnight from an external script.
+ *
+ * \section AstChanVar_devnotes Developer notes
+ * Variable handling is managed within \ref pbx.c
+ * You need to include pbx.h to reach these functions.
+ * - \ref pbx_builtin_setvar_helper()
+ * - \ref pbx_builtin_getvar_helper()
+ *
+ * The variables is a linked list stored in the channel data structure
+ * with the list starting at varshead in struct ast_channel
+ *
+ *
+ */
+
+/*! \page AstENUM ENUM
+ * \section enumreadme ENUM
+ * \arg Configuration: \ref Config_enum
+ * \arg \ref enum.c
+ * \arg \ref func_enum.c
+ *
+ * \verbinclude enum.txt
+ */
+
+/*! \page ConfigFiles Configuration files
+ * \section config Main configuration files
+ * \arg \link Config_ast asterisk.conf - the main configuration file \endlink
+ * \arg \link Config_ext extensions.conf - The Dial Plan \endlink
+ * \arg \link Config_mod modules.conf - which modules to load and not to load \endlink
+ * \arg \link Config_fea features.conf - call features (transfer, parking, etc) \endlink
+ * \section chanconf Channel configuration files
+ * \arg \link Config_iax IAX2 configuration \endlink
+ * \arg \link Config_sip SIP configuration \endlink
+ * \arg \link Config_mgcp MGCP configuration \endlink
+ * \arg \link Config_rtp RTP configuration \endlink
+ * \arg \link Config_zap Zaptel configuration \endlink
+ * \arg \link Config_oss OSS (sound card) configuration \endlink
+ * \arg \link Config_alsa ALSA (sound card) configuration \endlink
+ * \arg \link Config_agent Agent (proxy channel) configuration \endlink
+ * \arg \link Config_misdn MISDN Experimental ISDN BRI channel configuration \endlink
+ * \arg \link Config_h323 H.323 configuration \endlink
+ * \section appconf Application configuration files
+ * \arg \link Config_mm Meetme (conference bridge) configuration \endlink
+ * \arg \link Config_qu Queue system configuration \endlink
+ * \arg \link Config_vm Voicemail configuration \endlink
+ * \arg \link Config_followme Followme configuration \endlink
+ * \section cdrconf CDR configuration files
+ * \arg \link Config_cdr CDR configuration \endlink
+ * \arg \link cdr_custom Custom CDR driver configuration \endlink
+ * \arg \link cdr_ami Manager CDR driver configuration \endlink
+ * \arg \link cdr_odbc ODBC CDR driver configuration \endlink
+ * \arg \link cdr_pgsql PostgreSQL CDR driver configuration \endlink
+ * \arg \link cdr_sqlite SQLite CDR driver configuration \endlink
+ * \arg \link cdr_tds FreeTDS CDR driver configuration (Microsoft SQL Server) \endlink
+ * \section miscconf Miscellenaous configuration files
+ * \arg \link Config_adsi ADSI configuration \endlink
+ * \arg \link Config_ami AMI - Manager configuration \endlink
+ * \arg \link Config_ara Realtime configuration \endlink
+ * \arg \link Config_codec Codec configuration \endlink
+ * \arg \link Config_dun DUNDi configuration \endlink
+ * \arg \link Config_enum ENUM configuration \endlink
+ * \arg \link Config_moh Music on Hold configuration \endlink
+ * \arg \link Config_vm Voicemail configuration \endlink
+ * \arg \link res_config_sqlite SQLite Resource driver configuration \endlink
+ */
+
+/*! \page Config_ast Asterisk.conf
+ * \verbinclude asterisk-conf.txt
+ */
+/*! \page Config_mod Modules configuration
+ * All res_ resource modules are loaded with globals on, which means
+ * that non-static functions are callable from other modules.
+ *
+ * If you want your non res_* module to export functions to other modules
+ * you have to include it in the [global] section.
+ * \verbinclude modules.conf.sample
+ */
+
+/*! \page Config_fea Call features configuration
+ * \par See also
+ * \arg \ref res_features.c : Call feature implementation
+ * \section featconf features.conf
+ * \verbinclude features.conf.sample
+ */
+
+/*! \page Config_followme Followme: An application for simple follow-me calls
+ * \section followmeconf Followme.conf
+ * - See app_followme.c
+ * \verbinclude followme.conf.sample
+ */
+
+/*! \page Config_ext Extensions.conf - the Dial Plan
+ * \section dialplan Extensions.conf
+ * \verbinclude extensions.conf.sample
+ */
+
+/*! \page Config_iax IAX2 configuration
+ * IAX2 is implemented in \ref chan_iax2.c
+ * \arg \link Config_iax iax.conf Configuration file example \endlink
+ * \section iaxreadme IAX readme file
+ * \verbinclude iax.txt
+ * \section Config_iax IAX Configuration example
+ * \verbinclude iax.conf.sample
+ * \section iaxjitter IAX Jitterbuffer information
+ * \verbinclude jitterbuffer.txt
+ */
+
+/*! \page Config_iax IAX configuration
+ * \arg Implemented in \ref chan_iax2.c
+ * \section iaxconf iax.conf
+ * \verbinclude iax.conf.sample
+ */
+
+/*! \page Config_sip SIP configuration
+ * Also see \ref Config_rtp RTP configuration
+ * \arg Implemented in \ref chan_sip.c
+ * \section sipconf sip.conf
+ * \verbinclude sip.conf.sample
+ *
+ * \arg \b Back \ref chanconf
+ */
+
+/*! \page Config_mgcp MGCP configuration
+ * Also see \ref Config_rtp RTP configuration
+ * \arg Implemented in \ref chan_mgcp.c
+ * \section mgcpconf mgcp.conf
+ * \verbinclude mgcp.conf.sample
+ */
+
+/*! \page README_misdn MISDN documentation
+ * \arg See \ref Config_misdn
+ * \section mISDN configuration
+ * \verbinclude misdn.txt
+ */
+
+/*! \page Config_misdn MISDN configuration
+ * \arg Implemented in \ref chan_misdn.c
+ * \arg \ref README_misdn
+ * \arg See the mISDN home page: http://www.isdn4linux.de/mISDN/
+ * \section misdnconf misdn.conf
+ * \verbinclude misdn.conf.sample
+ */
+
+/*! \page Config_vm VoiceMail configuration
+ * \section vmconf voicemail.conf
+ * \arg Implemented in \ref app_voicemail.c
+ * \verbinclude voicemail.conf.sample
+ */
+
+/*! \page Config_zap Zaptel configuration
+ * \section zapconf zapata.conf
+ * \arg Implemented in \ref chan_zap.c
+ * \verbinclude zapata.conf.sample
+ */
+
+/*! \page Config_h323 H.323 channel driver information
+ * This is the configuration of the H.323 channel driver within the Asterisk
+ * distribution. There's another one, called OH323, in asterisk-addons
+ * \arg Implemented in \ref chan_h323.c
+ * \section h323conf h323.conf
+ * \ref chan_h323.c
+ */
+
+/*! \page Config_oss OSS configuration
+ * \section ossconf oss.conf
+ * \arg Implemented in \ref chan_oss.c
+ * \verbinclude oss.conf.sample
+ */
+
+/*! \page Config_alsa ALSA configuration
+ * \section alsaconf alsa.conf
+ * \arg Implemented in \ref chan_alsa.c
+ * \verbinclude alsa.conf.sample
+ */
+
+/*! \page Config_agent Agent configuration
+ * \section agentconf agents.conf
+ * The agent channel is a proxy channel for queues
+ * \arg Implemented in \ref chan_agent.c
+ * \verbinclude agents.conf.sample
+ */
+
+/*! \page Config_rtp RTP configuration
+ * \arg Implemented in \ref rtp.c
+ * Used in \ref chan_sip.c and \ref chan_mgcp.c (and various H.323 channels)
+ * \section rtpconf rtp.conf
+ * \verbinclude rtp.conf.sample
+ */
+
+/*! \page Config_dun DUNDi Configuration
+ * \arg See also \ref AstDUNDi
+ * \section dundiconf dundi.conf
+ * \verbinclude dundi.conf.sample
+ */
+
+/*! \page Config_enum ENUM Configuration
+ * \section enumconf enum.conf
+ * \arg See also \ref enumreadme
+ * \arg Implemented in \ref func_enum.c and \ref enum.c
+ * \verbinclude enum.conf.sample
+ */
+
+/*! \page cdr_custom Custom CDR Configuration
+ * \par See also
+ * \arg \ref cdrconf
+ * \arg \ref cdr_custom.c
+ * \verbinclude cdr_custom.conf.sample
+ */
+
+/*! \page cdr_ami Manager CDR driver configuration
+ * \par See also
+ * \arg \ref cdrconf
+ * \arg \ref AstAMI
+ * \arg \ref cdr_manager.c
+ * \verbinclude cdr_manager.conf.sample
+ */
+
+/*! \page cdr_odbc ODBC CDR driver configuration
+ * \arg See also \ref cdrconf
+ * \arg \ref cdr_odbc.c
+ * \verbinclude cdr_odbc.conf.sample
+ * See also:
+ * \arg http://www.unixodbc.org
+ */
+
+/*! \page cdr_pgsql PostgreSQL CDR driver configuration
+ * \arg See also \ref cdrconf
+ * \arg \ref cdr_pgsql.c
+ * See also:
+ * \arg http://www.postgresql.org
+ * \verbinclude cdr_pgsql.conf.sample
+ */
+
+/*! \page cdr_sqlite SQLite CDR driver configuration
+ * \arg See also \ref cdrconf
+ * \arg \ref cdr_sqlite.c
+ * See also:
+ * \arg http://www.sqlite.org
+ */
+
+/*! \page cdr_tds FreeTDS CDR driver configuration
+ * \arg See also \ref cdrconf
+ * See also:
+ * \arg http://www.freetds.org
+ * \verbinclude cdr_tds.conf.sample
+ */
+
+/*! \page Config_cdr CDR configuration
+ * \par See also
+ * \arg \ref cdr_drivers
+ * \arg \link Config_cdr CDR configuration \endlink
+ * \arg \link cdr_custom Custom CDR driver configuration \endlink
+ * \arg \link cdr_ami Manager CDR driver configuration \endlink
+ * \arg \link cdr_odbc ODBC CDR driver configuration \endlink
+ * \arg \link cdr_pgsql PostgreSQL CDR driver configuration \endlink
+ * \arg \link cdr_sqlite SQLite CDR driver configuration \endlink
+ * \arg \link cdr_tds FreeTDS CDR driver configuration (Microsoft SQL Server) \endlink
+ * \verbinclude cdr.conf.sample
+ */
+
+/*! \page Config_moh Music on Hold Configuration
+ * \arg Implemented in \ref res_musiconhold.c
+ * \section mohconf musiconhold.conf
+ * \verbinclude musiconhold.conf.sample
+ */
+
+/*! \page Config_adsi ADSI Configuration
+ * \section adsiconf adsi.conf
+ * \verbinclude adsi.conf.sample
+ */
+
+/*! \page Config_codec CODEC Configuration
+ * \section codecsconf codecs.conf
+ * \verbinclude codecs.conf.sample
+ */
+
+/*! \page Config_ara REALTIME Configuration
+ * \arg See also: \arg \link AstARA \endlink
+ * \section extconf extconfig.conf
+ * \verbinclude extconfig.conf.sample
+ */
+
+/*! \page Config_ami AMI configuration
+ * \arg See also: \arg \link AstAMI \endlink
+ * \section amiconf manager.conf
+ * \verbinclude manager.conf.sample
+ */
+
+/*! \page Config_qu ACD - Queue system configuration
+ * \arg Implemented in \ref app_queue.c
+ * \section quconf queues.conf
+ * \verbinclude queues.conf.sample
+ */
+
+/*! \page Config_mm Meetme - The conference bridge configuration
+ * \arg Implemented in \ref app_meetme.c
+ * \section mmconf meetme.conf
+ * \verbinclude meetme.conf.sample
+ */
+
+/*! \page SoundFiles Sound files
+ * \section SecSound Asterisk Sound files
+ * Asterisk includes a large number of sound files. Many of these
+ * are used by applications and demo scripts within asterisk.
+ *
+ * Additional sound files are available in the asterisk-addons
+ * repository on svn.digium.com
+ */
+
+/*! \addtogroup cdr_drivers Module: CDR Drivers
+ * \section CDR_generic Asterisk CDR Drivers
+ * \brief CDR drivers are loaded dynamically, each loaded CDR driver produce a billing record for each call.
+ * \arg \ref Config_mod "Modules Configuration"
+ * \arg \ref Config_cdr "CDR Configuration"
+ */
+
+
+/*! \addtogroup channel_drivers Module: Asterisk Channel Drivers
+ * \section channel_generic Asterisk Channel Drivers
+ * \brief Channel drivers are loaded dynamically.
+ * \arg \ref Config_mod "Modules Configuration"
+ */
+
+/*! \addtogroup applications Module: Dial plan applications
+ * \section app_generic Asterisk Dial Plan Applications
+ * \brief Applications support the dialplan. They register dynamically with \see ast_register_application() and unregister with \see ast_unregister_application()
+ * \par See also
+ * \arg \ref functions
+ *
+ */
+
+/*! \addtogroup functions Module: Dial plan functions
+ * \section func_generic Asterisk Dial Plan Functions
+ * \brief Functions support the dialplan. They do not change any property of a channel
+ * or touch a channel in any way.
+ * \par See also
+ * \arg \ref applications
+ *
+ */
+
+/*! \addtogroup codecs Module: Codecs
+ * \section codec_generic Asterisk Codec Modules
+ * Codecs are referenced in configuration files by name
+ * \par See also
+ * \arg \ref formats
+ *
+ */
+
+/*! \addtogroup formats Module: Media File Formats
+ * \section codec_generic Asterisk Format drivers
+ * Formats are modules that read or write media files to disk.
+ * \par See also
+ * \arg \ref codecs
+ */
+
+/*! \page AstHTTP AMI over HTTP support
+ * The http.c file includes support for manager transactions over
+ * http.
+ * \section ami AMI - The manager Interface
+ * \arg \link Config_ami Configuration file \endlink
+ */
+
+/*! \page res_config_sqlite SQLite Resource driver configuration
+ * \arg Implemented in \ref res_config_sqlite.c
+ * \arg Configuration file:
+ * \verbinclude res_config_sqlite.conf
+ * \arg SQL tables:
+ * \verbinclude res_config_sqlite.txt
+ * \arg See also:
+ * http://www.sqlite.org
+ */
diff --git a/trunk/include/asterisk/dsp.h b/trunk/include/asterisk/dsp.h
new file mode 100644
index 000000000..2664b9b3e
--- /dev/null
+++ b/trunk/include/asterisk/dsp.h
@@ -0,0 +1,111 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2005, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief Convenient Signal Processing routines
+ */
+
+#ifndef _ASTERISK_DSP_H
+#define _ASTERISK_DSP_H
+
+#define DSP_FEATURE_SILENCE_SUPPRESS (1 << 0)
+#define DSP_FEATURE_BUSY_DETECT (1 << 1)
+#define DSP_FEATURE_DTMF_DETECT (1 << 3)
+#define DSP_FEATURE_FAX_DETECT (1 << 4)
+
+#define DSP_DIGITMODE_DTMF 0 /*!< Detect DTMF digits */
+#define DSP_DIGITMODE_MF 1 /*!< Detect MF digits */
+
+#define DSP_DIGITMODE_NOQUELCH (1 << 8) /*!< Do not quelch DTMF from in-band */
+#define DSP_DIGITMODE_MUTECONF (1 << 9) /*!< Mute conference */
+#define DSP_DIGITMODE_MUTEMAX (1 << 10) /*!< Delay audio by a frame to try to extra quelch */
+#define DSP_DIGITMODE_RELAXDTMF (1 << 11) /*!< "Radio" mode (relaxed DTMF) */
+
+#define DSP_PROGRESS_TALK (1 << 16) /*!< Enable talk detection */
+#define DSP_PROGRESS_RINGING (1 << 17) /*!< Enable calling tone detection */
+#define DSP_PROGRESS_BUSY (1 << 18) /*!< Enable busy tone detection */
+#define DSP_PROGRESS_CONGESTION (1 << 19) /*!< Enable congestion tone detection */
+#define DSP_FEATURE_CALL_PROGRESS (DSP_PROGRESS_TALK | DSP_PROGRESS_RINGING | DSP_PROGRESS_BUSY | DSP_PROGRESS_CONGESTION)
+
+#define DSP_TONE_STATE_SILENCE 0
+#define DSP_TONE_STATE_RINGING 1
+#define DSP_TONE_STATE_DIALTONE 2
+#define DSP_TONE_STATE_TALKING 3
+#define DSP_TONE_STATE_BUSY 4
+#define DSP_TONE_STATE_SPECIAL1 5
+#define DSP_TONE_STATE_SPECIAL2 6
+#define DSP_TONE_STATE_SPECIAL3 7
+#define DSP_TONE_STATE_HUNGUP 8
+
+struct ast_dsp;
+
+struct ast_dsp *ast_dsp_new(void);
+void ast_dsp_free(struct ast_dsp *dsp);
+
+/*! \brief Set threshold value for silence */
+void ast_dsp_set_threshold(struct ast_dsp *dsp, int threshold);
+
+/*! \brief Set number of required cadences for busy */
+void ast_dsp_set_busy_count(struct ast_dsp *dsp, int cadences);
+
+/*! \brief Set expected lengths of the busy tone */
+void ast_dsp_set_busy_pattern(struct ast_dsp *dsp, int tonelength, int quietlength);
+
+/*! \brief Scans for progress indication in audio */
+int ast_dsp_call_progress(struct ast_dsp *dsp, struct ast_frame *inf);
+
+/*! \brief Set zone for doing progress detection */
+int ast_dsp_set_call_progress_zone(struct ast_dsp *dsp, char *zone);
+
+/*! \brief Return AST_FRAME_NULL frames when there is silence, AST_FRAME_BUSY on
+ busies, and call progress, all dependent upon which features are enabled */
+struct ast_frame *ast_dsp_process(struct ast_channel *chan, struct ast_dsp *dsp, struct ast_frame *inf);
+
+/*! \brief Return non-zero if this is silence. Updates "totalsilence" with the total
+ number of seconds of silence */
+int ast_dsp_silence(struct ast_dsp *dsp, struct ast_frame *f, int *totalsilence);
+
+/*! \brief Return non-zero if historically this should be a busy, request that
+ ast_dsp_silence has already been called */
+int ast_dsp_busydetect(struct ast_dsp *dsp);
+
+/*! \brief Return non-zero if DTMF hit was found */
+int ast_dsp_digitdetect(struct ast_dsp *dsp, struct ast_frame *f);
+
+/*! \brief Reset total silence count */
+void ast_dsp_reset(struct ast_dsp *dsp);
+
+/*! \brief Reset DTMF detector */
+void ast_dsp_digitreset(struct ast_dsp *dsp);
+
+/*! \brief Select feature set */
+void ast_dsp_set_features(struct ast_dsp *dsp, int features);
+
+/*! \brief Get pending DTMF/MF digits */
+int ast_dsp_getdigits(struct ast_dsp *dsp, char *buf, int max);
+
+/*! \brief Set digit mode */
+int ast_dsp_digitmode(struct ast_dsp *dsp, int digitmode);
+
+/*! \brief Get tstate (Tone State) */
+int ast_dsp_get_tstate(struct ast_dsp *dsp);
+
+/*! \brief Get tcount (Threshold counter) */
+int ast_dsp_get_tcount(struct ast_dsp *dsp);
+
+#endif /* _ASTERISK_DSP_H */
diff --git a/trunk/include/asterisk/dundi.h b/trunk/include/asterisk/dundi.h
new file mode 100644
index 000000000..e588338ae
--- /dev/null
+++ b/trunk/include/asterisk/dundi.h
@@ -0,0 +1,231 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2005, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief Distributed Universal Number Discovery (DUNDi)
+ * See also \arg \ref AstDUNDi
+ */
+
+#ifndef _ASTERISK_DUNDI_H
+#define _ASTERISK_DUNDI_H
+
+#include "asterisk/channel.h"
+
+#define DUNDI_PORT 4520
+
+/*!\brief A DUNDi Entity ID is essentially a MAC address, brief and unique */
+struct _dundi_eid {
+ unsigned char eid[6];
+} __attribute__ ((__packed__));
+
+typedef struct _dundi_eid dundi_eid;
+
+struct dundi_hdr {
+ unsigned short strans; /*!< Source transaction */
+ unsigned short dtrans; /*!< Destination transaction */
+ unsigned char iseqno; /*!< Next expected incoming sequence number */
+ unsigned char oseqno; /*!< Outgoing sequence number */
+ unsigned char cmdresp; /*!< Command / Response */
+ unsigned char cmdflags; /*!< Command / Response specific flags*/
+ unsigned char ies[0];
+} __attribute__ ((__packed__));
+
+struct dundi_ie_hdr {
+ unsigned char ie;
+ unsigned char len;
+ unsigned char iedata[0];
+} __attribute__ ((__packed__));
+
+#define DUNDI_FLAG_RETRANS (1 << 16) /*!< Applies to dtrans */
+#define DUNDI_FLAG_RESERVED (1 << 16) /*!< Applies to strans */
+
+#define DUNDI_PROTO_NONE 0 /*!< No answer yet */
+#define DUNDI_PROTO_IAX 1 /*!< IAX version 2 */
+#define DUNDI_PROTO_SIP 2 /*!< Session Initiation Protocol */
+#define DUNDI_PROTO_H323 3 /*!< ITU H.323 */
+
+#define DUNDI_FLAG_NONEXISTENT (0) /*!< Isn't and can't be a valid number */
+#define DUNDI_FLAG_EXISTS (1 << 0) /*!< Is a valid number */
+#define DUNDI_FLAG_MATCHMORE (1 << 1) /*!< Might be valid if you add more digits */
+#define DUNDI_FLAG_CANMATCH (1 << 2) /*!< Might be a match */
+#define DUNDI_FLAG_IGNOREPAT (1 << 3) /*!< Keep dialtone */
+#define DUNDI_FLAG_RESIDENTIAL (1 << 4) /*!< Destination known to be residential */
+#define DUNDI_FLAG_COMMERCIAL (1 << 5) /*!< Destination known to be commercial */
+#define DUNDI_FLAG_MOBILE (1 << 6) /*!< Destination known to be cellular/mobile */
+#define DUNDI_FLAG_NOUNSOLICITED (1 << 7) /*!< No unsolicited calls of any kind through this route */
+#define DUNDI_FLAG_NOCOMUNSOLICIT (1 << 8) /*!< No commercial unsolicited calls through this route */
+
+#define DUNDI_HINT_NONE (0)
+#define DUNDI_HINT_TTL_EXPIRED (1 << 0) /*!< TTL Expired */
+#define DUNDI_HINT_DONT_ASK (1 << 1) /*!< Don't ask for anything beginning with data */
+#define DUNDI_HINT_UNAFFECTED (1 << 2) /*!< Answer not affected by entity list */
+
+struct dundi_encblock { /*!< AES-128 encrypted block */
+ unsigned char iv[16]; /*!< Initialization vector of random data */
+ unsigned char encdata[0]; /*!< Encrypted / compressed data */
+} __attribute__ ((__packed__));
+
+struct dundi_answer {
+ dundi_eid eid; /*!< Original source of answer */
+ unsigned char protocol; /*!< Protocol (DUNDI_PROTO_*) */
+ unsigned short flags; /*!< Flags relating to answer */
+ unsigned short weight; /*!< Weight of answers */
+ unsigned char data[0]; /*!< Protocol specific URI */
+} __attribute__ ((__packed__));
+
+struct dundi_hint {
+ unsigned short flags; /*!< Flags relating to answer */
+ unsigned char data[0]; /*!< For data for hint */
+} __attribute__ ((__packed__));
+
+#define DUNDI_CAUSE_SUCCESS 0 /*!< Success */
+#define DUNDI_CAUSE_GENERAL 1 /*!< General unspecified failure */
+#define DUNDI_CAUSE_DYNAMIC 2 /*!< Requested entity is dynamic */
+#define DUNDI_CAUSE_NOAUTH 3 /*!< No or improper authorization */
+#define DUNDI_CAUSE_DUPLICATE 4 /*!< Duplicate request */
+#define DUNDI_CAUSE_TTL_EXPIRED 5 /*!< Expired TTL */
+#define DUNDI_CAUSE_NEEDKEY 6 /*!< Need new session key to decode */
+#define DUNDI_CAUSE_BADENCRYPT 7 /*!< Badly encrypted data */
+
+struct dundi_cause {
+ unsigned char causecode; /*!< Numerical cause (DUNDI_CAUSE_*) */
+ char desc[0]; /*!< Textual description */
+} __attribute__ ((__packed__));
+
+struct dundi_peer_status {
+ unsigned int flags;
+ unsigned short netlag;
+ unsigned short querylag;
+ dundi_eid peereid;
+} __attribute__ ((__packed__));
+
+#define DUNDI_PEER_PRIMARY (1 << 0)
+#define DUNDI_PEER_SECONDARY (1 << 1)
+#define DUNDI_PEER_UNAVAILABLE (1 << 2)
+#define DUNDI_PEER_REGISTERED (1 << 3)
+#define DUNDI_PEER_MOD_OUTBOUND (1 << 4)
+#define DUNDI_PEER_MOD_INBOUND (1 << 5)
+#define DUNDI_PEER_PCMOD_OUTBOUND (1 << 6)
+#define DUNDI_PEER_PCMOD_INBOUND (1 << 7)
+
+#define DUNDI_COMMAND_FINAL (0x80) /*!< Or'd with other flags */
+
+#define DUNDI_COMMAND_ACK (0 | 0x40) /*!< Ack a message */
+#define DUNDI_COMMAND_DPDISCOVER 1 /*!< Request discovery */
+#define DUNDI_COMMAND_DPRESPONSE (2 | 0x40) /*!< Respond to a discovery request */
+#define DUNDI_COMMAND_EIDQUERY 3 /*!< Request information for a peer */
+#define DUNDI_COMMAND_EIDRESPONSE (4 | 0x40) /*!< Response to a peer query */
+#define DUNDI_COMMAND_PRECACHERQ 5 /*!< Pre-cache Request */
+#define DUNDI_COMMAND_PRECACHERP (6 | 0x40) /*!< Pre-cache Response */
+#define DUNDI_COMMAND_INVALID (7 | 0x40) /*!< Invalid dialog state (does not require ack) */
+#define DUNDI_COMMAND_UNKNOWN (8 | 0x40) /*!< Unknown command */
+#define DUNDI_COMMAND_NULL 9 /*!< No-op */
+#define DUNDI_COMMAND_REGREQ (10) /*!< Register Request */
+#define DUNDI_COMMAND_REGRESPONSE (11 | 0x40) /*!< Register Response */
+#define DUNDI_COMMAND_CANCEL (12) /*!< Cancel transaction entirely */
+#define DUNDI_COMMAND_ENCRYPT (13) /*!< Send an encrypted message */
+#define DUNDI_COMMAND_ENCREJ (14 | 0x40) /*!< Reject an encrypted message */
+
+#define DUNDI_COMMAND_STATUS 15 /*!< Status command */
+
+/*
+ * Remember that some information elements may occur
+ * more than one time within a message
+ */
+
+#define DUNDI_IE_EID 1 /*!< Entity identifier (dundi_eid) */
+#define DUNDI_IE_CALLED_CONTEXT 2 /*!< DUNDi Context (string) */
+#define DUNDI_IE_CALLED_NUMBER 3 /*!< Number of equivalent (string) */
+#define DUNDI_IE_EID_DIRECT 4 /*!< Entity identifier (dundi_eid), direct connect */
+#define DUNDI_IE_ANSWER 5 /*!< An answer (struct dundi_answer) */
+#define DUNDI_IE_TTL 6 /*!< Max TTL for this request / Remaining TTL for the response (short)*/
+#define DUNDI_IE_VERSION 10 /*!< DUNDi version (should be 1) (short) */
+#define DUNDI_IE_EXPIRATION 11 /*!< Recommended expiration (short) */
+#define DUNDI_IE_UNKNOWN 12 /*!< Unknown command (byte) */
+#define DUNDI_IE_CAUSE 14 /*!< Success or cause of failure */
+#define DUNDI_IE_REQEID 15 /*!< EID being requested for EIDQUERY*/
+#define DUNDI_IE_ENCDATA 16 /*!< AES-128 encrypted data */
+#define DUNDI_IE_SHAREDKEY 17 /*!< RSA encrypted AES-128 key */
+#define DUNDI_IE_SIGNATURE 18 /*!< RSA Signature of encrypted shared key */
+#define DUNDI_IE_KEYCRC32 19 /*!< CRC32 of encrypted key (int) */
+#define DUNDI_IE_HINT 20 /*!< Answer hints (struct ast_hint) */
+
+#define DUNDI_IE_DEPARTMENT 21 /*!< Department, for EIDQUERY (string) */
+#define DUNDI_IE_ORGANIZATION 22 /*!< Organization, for EIDQUERY (string) */
+#define DUNDI_IE_LOCALITY 23 /*!< City/Locality, for EIDQUERY (string) */
+#define DUNDI_IE_STATE_PROV 24 /*!< State/Province, for EIDQUERY (string) */
+#define DUNDI_IE_COUNTRY 25 /*!< Country, for EIDQUERY (string) */
+#define DUNDI_IE_EMAIL 26 /*!< E-mail addy, for EIDQUERY (string) */
+#define DUNDI_IE_PHONE 27 /*!< Contact Phone, for EIDQUERY (string) */
+#define DUNDI_IE_IPADDR 28 /*!< IP Address, for EIDQUERY (string) */
+#define DUNDI_IE_CACHEBYPASS 29 /*!< Bypass cache (empty) */
+
+#define DUNDI_IE_PEERSTATUS 30 /*!< Peer/peer status (struct dundi_peer_status) */
+
+#define DUNDI_FLUFF_TIME 2000 /*!< Amount of time for answer */
+#define DUNDI_TTL_TIME 200 /*!< Incremental average time */
+
+#define DUNDI_DEFAULT_RETRANS 5
+#define DUNDI_DEFAULT_RETRANS_TIMER 1000
+#define DUNDI_DEFAULT_TTL 120 /*!< In seconds/hops like TTL */
+#define DUNDI_DEFAULT_VERSION 1
+#define DUNDI_DEFAULT_CACHE_TIME 3600 /*!< In seconds */
+#define DUNDI_DEFAULT_KEY_EXPIRE 3600 /*!< Life of shared key In seconds */
+#define DUNDI_DEF_EMPTY_CACHE_TIME 60 /*!< In seconds, cache of empty answer */
+#define DUNDI_WINDOW 1 /*!< Max 1 message in window */
+
+#define DEFAULT_MAXMS 2000
+
+struct dundi_result {
+ unsigned int flags;
+ int weight;
+ int expiration;
+ int techint;
+ dundi_eid eid;
+ char eid_str[20];
+ char tech[10];
+ char dest[256];
+};
+
+struct dundi_entity_info {
+ char country[80];
+ char stateprov[80];
+ char locality[80];
+ char org[80];
+ char orgunit[80];
+ char email[80];
+ char phone[80];
+ char ipaddr[80];
+};
+
+/*!
+ * \brief Lookup the given number in the given dundi context.
+ * Lookup number in a given dundi context (if unspecified use e164), the given callerid (if specified)
+ * and return up to maxret results in the array specified.
+ * \retval the number of results found.
+ * \retval -1 on a hangup of the channel.
+*/
+int dundi_lookup(struct dundi_result *result, int maxret, struct ast_channel *chan, const char *dcontext, const char *number, int nocache);
+
+/*! \brief Retrieve information on a specific EID */
+int dundi_query_eid(struct dundi_entity_info *dei, const char *dcontext, dundi_eid eid);
+
+/*! \brief Pre-cache to push upstream peers */
+int dundi_precache(const char *dcontext, const char *number);
+
+#endif /* _ASTERISK_DUNDI_H */
diff --git a/trunk/include/asterisk/endian.h b/trunk/include/asterisk/endian.h
new file mode 100644
index 000000000..302a0aa7d
--- /dev/null
+++ b/trunk/include/asterisk/endian.h
@@ -0,0 +1,69 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2005, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief Asterisk architecture endianess compatibility definitions
+ */
+
+#ifndef _ASTERISK_ENDIAN_H
+#define _ASTERISK_ENDIAN_H
+
+/*
+ * Autodetect system endianess
+ */
+
+#ifndef __BYTE_ORDER
+#ifdef __linux__
+#include <endian.h>
+#elif defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__APPLE__)
+#include <machine/endian.h>
+#define __BYTE_ORDER BYTE_ORDER
+#define __LITTLE_ENDIAN LITTLE_ENDIAN
+#define __BIG_ENDIAN BIG_ENDIAN
+#else
+
+#ifndef __LITTLE_ENDIAN
+#define __LITTLE_ENDIAN 1234
+#endif
+
+#ifndef __BIG_ENDIAN
+#define __BIG_ENDIAN 4321
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define __BYTE_ORDER __LITTLE_ENDIAN
+#endif /* __LITTLE_ENDIAN */
+
+#if defined(i386) || defined(__i386__)
+#define __BYTE_ORDER __LITTLE_ENDIAN
+#endif /* defined i386 */
+
+#if defined(sun) && defined(unix) && defined(sparc)
+#define __BYTE_ORDER __BIG_ENDIAN
+#endif /* sun unix sparc */
+
+#endif /* linux */
+
+#endif /* __BYTE_ORDER */
+
+#ifndef __BYTE_ORDER
+#error Need to know endianess
+#endif /* __BYTE_ORDER */
+
+#endif /* _ASTERISK_ENDIAN_H */
+
diff --git a/trunk/include/asterisk/enum.h b/trunk/include/asterisk/enum.h
new file mode 100644
index 000000000..d6bbea294
--- /dev/null
+++ b/trunk/include/asterisk/enum.h
@@ -0,0 +1,90 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2005, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file enum.h
+ \brief DNS and ENUM functions
+*/
+
+#ifndef _ASTERISK_ENUM_H
+#define _ASTERISK_ENUM_H
+
+#include "asterisk/channel.h"
+
+struct naptr {
+ unsigned short order;
+ unsigned short pref;
+} __attribute__ ((__packed__));
+
+struct enum_naptr_rr {
+ struct naptr naptr; /*!< order and preference of RR */
+ char *result; /*!< result of naptr parsing,e.g.: tel:+5553 */
+ char *tech; /*!< Technology (from URL scheme) */
+ int sort_pos; /*!< sort position */
+};
+
+struct enum_context {
+ char *dst; /*!< Destination part of URL from ENUM */
+ int dstlen; /*!< Length */
+ char *tech; /*!< Technology (from URL scheme) */
+ int techlen; /*!< Length */
+ char *txt; /*!< TXT record in TXT lookup */
+ int txtlen; /*!< Length */
+ char *naptrinput; /*!< The number to lookup */
+ int position; /*!< used as counter for RRs or specifies position of required RR */
+ int options; /*!< options , see ENUMLOOKUP_OPTIONS_* defined above */
+ struct enum_naptr_rr *naptr_rrs; /*!< array of parsed NAPTR RRs */
+ int naptr_rrs_count; /*!< Size of array naptr_rrs */
+};
+
+
+/*! \brief Lookup entry in ENUM
+ \param chan Channel
+ \param number E164 number with or without the leading +
+ \param location Number returned (or SIP uri)
+ \param maxloc Max length
+ \param technology Technology (from url scheme in response)
+ You can set it to get particular answer RR, if there are many techs in DNS response, example: "sip"
+ If you need any record, then set it to empty string
+ \param maxtech Max length
+ \param suffix Zone suffix (if is NULL then use enum.conf 'search' variable)
+ \param options Options ('c' to count number of NAPTR RR)
+ \param record The position of required RR in the answer list
+ \param argcontext Argument for caching results into an enum_context pointer (NULL is used for not caching)
+ \retval 1 if found
+ \retval 0 if not found
+ \retval -1 on hangup
+*/
+int ast_get_enum(struct ast_channel *chan, const char *number, char *location, int maxloc, char *technology,
+ int maxtech, char* suffix, char* options, unsigned int record, struct enum_context **argcontext);
+
+/*! \brief Lookup DNS TXT record (used by app TXTCIDnum
+ \param chan Channel
+ \param number E164 number with or without the leading +
+ \param location Number returned (or SIP uri)
+ \param maxloc Max length of number
+ \param technology Technology (not used in TXT records)
+ \param maxtech Max length
+ \param txt Text string (return value)
+ \param maxtxt Max length of "txt"
+*/
+int ast_get_txt(struct ast_channel *chan, const char *number, char *location, int maxloc, char *technology, int maxtech, char *txt, int maxtxt);
+
+int ast_enum_init(void);
+int ast_enum_reload(void);
+
+#endif /* _ASTERISK_ENUM_H */
diff --git a/trunk/include/asterisk/event.h b/trunk/include/asterisk/event.h
new file mode 100644
index 000000000..6946b54e1
--- /dev/null
+++ b/trunk/include/asterisk/event.h
@@ -0,0 +1,482 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2007, Digium, Inc.
+ *
+ * Russell Bryant <russell@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*!
+ * \file
+ * \author Russell Bryant <russell@digium.com>
+ * \ref AstGenericEvents
+ * \page AstGenericEvents Generic event system
+ *
+ * The purpose of this API is to provide a generic way to share events between
+ * Asterisk modules. Code can generate events, and other code can subscribe to
+ * them.
+ *
+ * Events have an associated event type, as well as information elements. The
+ * information elements are the meta data that go along with each event. For
+ * example, in the case of message waiting indication, the event type is MWI,
+ * and each MWI event contains at least three information elements: the
+ * mailbox, the number of new messages, and the number of old messages.
+ *
+ * Subscriptions to events consist of an event type and information elements,
+ * as well. Subscriptions can be to all events, or a certain subset of events.
+ * If an event type is provided, only events of that type will be sent to this
+ * subscriber. Furthermore, if information elements are supplied with the
+ * subscription, only events that contain the specified information elements
+ * with specified values will be sent to the subscriber. For example, when a
+ * SIP phone subscribes to MWI for mailbox 1234, then chan_sip can subscribe
+ * to internal Asterisk MWI events with the MAILBOX information element with
+ * a value of "1234".
+ *
+ * Another key feature of this event system is the ability to cache events.
+ * It is useful for some types of events to be able to remember the last known
+ * value. These are usually events that indicate some kind of state change.
+ * In the example of MWI, app_voicemail can instruct the event core to cache
+ * these events based on the mailbox. So, the last known MWI state of each
+ * mailbox will be cached, and other modules can retrieve this information
+ * on demand without having to poll the mailbox directly.
+ */
+
+#ifndef AST_EVENT_H
+#define AST_EVENT_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+#include "asterisk/event_defs.h"
+
+/*!
+ * \brief Subscriber event callback type
+ *
+ * \param event the event being passed to the subscriber
+ * \param userdata the data provider in the call to ast_event_subscribe()
+ *
+ * \return The event callbacks do not return anything.
+ */
+typedef void (*ast_event_cb_t)(const struct ast_event *event, void *userdata);
+
+/*!
+ * \brief Subscribe to events
+ *
+ * \param event_type The type of events to subscribe to
+ * \param cb The function to be called with events
+ * \param userdata data to be passed to the event callback
+ *
+ * The rest of the arguments to this function specify additional parameters for
+ * the subscription to filter which events are passed to this subscriber. The
+ * arguments must be in sets of:
+ * \code
+ * <enum ast_event_ie_type>, [enum ast_event_ie_pltype, [payload] ]
+ * \endcode
+ * and must end with AST_EVENT_IE_END.
+ *
+ * If the ie_type specified is *not* AST_EVENT_IE_END, then it must be followed
+ * by a valid IE payload type. If the payload type specified is
+ * AST_EVENT_IE_PLTYPE_EXISTS, then the 3rd argument should not be provided.
+ * Otherwise, a payload must also be specified.
+ *
+ * \return This returns a reference to the subscription for use with
+ * un-subscribing later. If there is a failure in creating the
+ * subscription, NULL will be returned.
+ *
+ * Example usage:
+ *
+ * \code
+ * peer->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, peer,
+ * AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, peer->mailbox,
+ * AST_EVENT_IE_END);
+ * \endcode
+ *
+ * This creates a subscription to AST_EVENT_MWI events that contain an
+ * information element, AST_EVENT_IE_MAILBOX, with the same string value
+ * contained in peer->mailbox. Also, the event callback will be passed a
+ * pointer to the peer.
+ */
+struct ast_event_sub *ast_event_subscribe(enum ast_event_type event_type,
+ ast_event_cb_t cb, void *userdata, ...);
+
+/*!
+ * \brief Un-subscribe from events
+ *
+ * \param event_sub This is the reference to the subscription returned by
+ * ast_event_subscribe.
+ *
+ * \return Nothing
+ */
+void ast_event_unsubscribe(struct ast_event_sub *event_sub);
+
+/*!
+ * \brief Check if subscribers exist
+ *
+ * \param event_type This is the type of event that the caller would like to
+ * check for subscribers to.
+ *
+ * The rest of the arguments to this function specify additional parameters for
+ * checking for subscriptions to subsets of an event type. The arguments must
+ * in sets of:
+ * \code
+ * <enum ast_event_ie_type>, [enum ast_event_ie_pltype, [payload] ]
+ * \endcode
+ * and must end with AST_EVENT_IE_END.
+ *
+ * If the ie_type specified is *not* AST_EVENT_IE_END, then it must be followed
+ * by a valid IE payload type. If the payload type specified is
+ * AST_EVENT_IE_PLTYPE_EXISTS, then the 3rd argument should not be provided.
+ * Otherwise, a payload must also be specified.
+ *
+ * \return This returns one of the values defined in the ast_event_subscriber_res
+ * enum which will indicate if subscribers exist that match the given
+ * criteria.
+ *
+ * Example usage:
+ *
+ * \code
+ * if (ast_event_check_subscriber(AST_EVENT_MWI,
+ * AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
+ * AST_EVENT_IE_END) == AST_EVENT_SUB_NONE) {
+ * return;
+ * }
+ * \endcode
+ *
+ * This example will check if there are any subscribers to MWI events for the
+ * mailbox defined in the "mailbox" variable.
+ */
+enum ast_event_subscriber_res ast_event_check_subscriber(enum ast_event_type event_type, ...);
+
+/*!
+ * \brief Report current subscriptions to a subscription subscriber
+ *
+ * \arg sub the subscription subscriber
+ *
+ * \return nothing
+ *
+ * This reports all of the current subscribers to a subscriber of
+ * subscribers to a specific event type. (Try saying that a few times fast).
+ *
+ * The idea here is that it is sometimes very useful for a module to know when
+ * someone subscribes to events. However, when they first subscribe, this
+ * provides that module the ability to request the event core report to them
+ * all of the subscriptions to that event type that already exist.
+ */
+void ast_event_report_subs(const struct ast_event_sub *sub);
+
+/*!
+ * \brief Create a new event
+ *
+ * \param event_type The type of event to create
+ *
+ * The rest of the arguments to this function specify information elements to
+ * add to the event. They are specified in the form:
+ * \code
+ * <enum ast_event_ie_type>, [enum ast_event_ie_pltype, [payload] ]
+ * \endcode
+ * and must end with AST_EVENT_IE_END.
+ *
+ * If the ie_type specified is *not* AST_EVENT_IE_END, then it must be followed
+ * by a valid IE payload type. The payload type, EXISTS, should not be used here
+ * because it makes no sense to do so. So, a payload must also be specified
+ * after the IE payload type.
+ *
+ * \return This returns the event that has been created. If there is an error
+ * creating the event, NULL will be returned.
+ *
+ * Example usage:
+ *
+ * \code
+ * if (!(event = ast_event_new(AST_EVENT_MWI,
+ * AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
+ * AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_UINT, new,
+ * AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_UINT, old,
+ * AST_EVENT_IE_END))) {
+ * return;
+ * }
+ * \endcode
+ *
+ * This creates a MWI event with 3 information elements, a mailbox which is
+ * a string, and the number of new and old messages, specified as integers.
+ */
+struct ast_event *ast_event_new(enum ast_event_type event_type, ...);
+
+/*!
+ * \brief Destroy an event
+ *
+ * \param event the event to destroy
+ *
+ * \return Nothing
+ *
+ * \note Events that have been queued should *not* be destroyed by the code that
+ * created the event. It will be automatically destroyed after being
+ * dispatched to the appropriate subscribers.
+ */
+void ast_event_destroy(struct ast_event *event);
+
+/*!
+ * \brief Queue an event
+ *
+ * \param event the event to be queued
+ *
+ * \retval zero success
+ * \retval non-zero failure
+ *
+ * This function queues an event to be dispatched to all of the appropriate
+ * subscribers. This function will not block while the event is being
+ * dispatched because a pool of event dispatching threads handle the event
+ * queue.
+ */
+int ast_event_queue(struct ast_event *event);
+
+/*!
+ * \brief Queue and cache an event
+ *
+ * \param event the event to be queued and cached
+ *
+ * The rest of the arguments to this function specify information elements to
+ * use for determining which events in the cache that this event should replace.
+ * All events in the cache that match the specified criteria will be removed from
+ * the cache and then this one will be added. The arguments are specified in
+ * the form:
+ *
+ * \code
+ * <enum ast_event_ie_type>, [enum ast_event_ie_pltype]
+ * \endcode
+ * and must end with AST_EVENT_IE_END.
+ *
+ * If the ie_type specified is *not* AST_EVENT_IE_END, then it must be followed
+ * by a valid IE payload type. If the payload type given is EXISTS, then all
+ * events that contain that information element will be removed from the cache.
+ * Otherwise, all events in the cache that contain an information element with
+ * the same value as the new event will be removed.
+ *
+ * \note If more than one IE parameter is specified, they *all* must match for
+ * the event to be removed from the cache.
+ *
+ * Example usage:
+ *
+ * \code
+ * ast_event_queue_and_cache(event,
+ * AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR,
+ * AST_EVENT_IE_END);
+ * \endcode
+ *
+ * This example queues and caches an event. Any events in the cache that have
+ * the same MAILBOX information element as this event will be removed.
+ *
+ * The purpose of caching events is so that the core can retain the last known
+ * information for events that represent some sort of state. That way, when
+ * code needs to find out the current state, it can query the cache.
+ */
+int ast_event_queue_and_cache(struct ast_event *event, ...);
+
+/*!
+ * \brief Retrieve an event from the cache
+ *
+ * \param ast_event_type The type of event to retrieve from the cache
+ *
+ * The rest of the arguments to this function specify information elements to
+ * match for retrieving events from the cache. They are specified in the form:
+ * \code
+ * <enum ast_event_ie_type>, [enum ast_event_ie_pltype, [payload] ]
+ * \endcode
+ * and must end with AST_EVENT_IE_END.
+ *
+ * If the ie_type specified is *not* AST_EVENT_IE_END, then it must be followed
+ * by a valid IE payload type. If the payload type specified is
+ * AST_EVENT_IE_PLTYPE_EXISTS, then the 3rd argument should not be provided.
+ * Otherwise, a payload must also be specified.
+ *
+ * \return A reference to an event retrieved from the cache. If no event was
+ * found that matches the specified criteria, then NULL will be returned.
+ *
+ * \note If more than one event in the cache matches the specified criteria, only
+ * one will be returned, and it is undefined which one it will be.
+ *
+ * \note The caller of this function *must* call ast_event_destroy() on the
+ * returned event after it is done using it.
+ *
+ * Example Usage:
+ *
+ * \code
+ * event = ast_event_get_cached(AST_EVENT_MWI,
+ * AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
+ * AST_EVENT_IE_END);
+ * \endcode
+ *
+ * This example will check for an MWI event in the cache that matches the
+ * specified mailbox. This would be the way to find out the last known state
+ * of a mailbox without having to poll the mailbox directly.
+ */
+struct ast_event *ast_event_get_cached(enum ast_event_type, ...);
+
+/*!
+ * \brief Append an information element that has a string payload
+ *
+ * \param event the event that the IE will be appended to
+ * \param ie_type the type of IE to append
+ * \param str The string for the payload of the IE
+ *
+ * \retval 0 success
+ * \retval -1 failure
+ *
+ * The pointer to the event will get updated with the new location for the event
+ * that now contains the appended information element. If the re-allocation of
+ * the memory for this event fails, it will be set to NULL.
+ */
+int ast_event_append_ie_str(struct ast_event **event, enum ast_event_ie_type ie_type,
+ const char *str);
+
+/*!
+ * \brief Append an information element that has an integer payload
+ *
+ * \param event the event that the IE will be appended to
+ * \param ie_type the type of IE to append
+ * \param data The integer for the payload of the IE
+ *
+ * \retval 0 success
+ * \retval -1 failure
+ *
+ * The pointer to the event will get updated with the new location for the event
+ * that now contains the appended information element. If the re-allocation of
+ * the memory for this event fails, it will be set to NULL.
+ */
+int ast_event_append_ie_uint(struct ast_event **event, enum ast_event_ie_type ie_type,
+ uint32_t data);
+
+/*!
+ * \brief Append an information element that has a raw payload
+ *
+ * \param event the event that the IE will be appended to
+ * \param ie_type the type of IE to append
+ * \param data A pointer to the raw data for the payload of the IE
+ * \param data_len The amount of data to copy into the payload
+ *
+ * \retval 0 success
+ * \retval -1 failure
+ *
+ * The pointer to the event will get updated with the new location for the event
+ * that now contains the appended information element. If the re-allocation of
+ * the memory for this event fails, it will be set to NULL.
+ */
+int ast_event_append_ie_raw(struct ast_event **event, enum ast_event_ie_type ie_type,
+ const void *data, size_t data_len);
+
+/*!
+ * \brief Get the value of an information element that has an integer payload
+ *
+ * \param event The event to get the IE from
+ * \param ie_type the type of information element to retrieve
+ *
+ * \return This returns the payload of the information element with the given type.
+ * However, an IE with a payload of 0, and the case where no IE is found
+ * yield the same return value.
+ */
+uint32_t ast_event_get_ie_uint(const struct ast_event *event, enum ast_event_ie_type ie_type);
+
+/*!
+ * \brief Get the value of an information element that has a string payload
+ *
+ * \param event The event to get the IE from
+ * \param ie_type the type of information element to retrieve
+ *
+ * \return This returns the payload of the information element with the given type.
+ * If the information element isn't found, NULL will be returned.
+ */
+const char *ast_event_get_ie_str(const struct ast_event *event, enum ast_event_ie_type ie_type);
+
+/*!
+ * \brief Get the value of an information element that has a raw payload
+ *
+ * \param event The event to get the IE from
+ * \param ie_type the type of information element to retrieve
+ *
+ * \return This returns the payload of the information element with the given type.
+ * If the information element isn't found, NULL will be returned.
+ */
+const void *ast_event_get_ie_raw(const struct ast_event *event, enum ast_event_ie_type ie_type);
+
+/*!
+ * \brief Get the type for an event
+ *
+ * \param event the event to get the type for
+ *
+ * \return the event type as represented by one of the values in the
+ * ast_event_type enum
+ */
+enum ast_event_type ast_event_get_type(const struct ast_event *event);
+
+/*!
+ * \brief Initialize an event iterator instance
+ *
+ * \param iterator The iterator instance to initialize
+ * \param event The event that will be iterated through
+ *
+ * \return Nothing
+ */
+void ast_event_iterator_init(struct ast_event_iterator *iterator, const struct ast_event *event);
+
+/*!
+ * \brief Move iterator instance to next IE
+ *
+ * \param iterator The iterator instance
+ *
+ * \retval 0 on success
+ * \retval -1 if end is reached
+ */
+int ast_event_iterator_next(struct ast_event_iterator *iterator);
+
+/*!
+ * \brief Get the type of the current IE in the iterator instance
+ *
+ * \param iterator The iterator instance
+ *
+ * \return the ie type as represented by one of the value sin the
+ * ast_event_ie_type enum
+ */
+enum ast_event_ie_type ast_event_iterator_get_ie_type(struct ast_event_iterator *iterator);
+
+/*!
+ * \brief Get the value of the current IE in the ierator as an integer payload
+ *
+ * \param iterator The iterator instance
+ *
+ * \return This returns the payload of the information element as a uint.
+ */
+uint32_t ast_event_iterator_get_ie_uint(struct ast_event_iterator *iterator);
+
+/*!
+ * \brief Get the value of the current IE in the iterator as a string payload
+ *
+ * \param iterator The iterator instance
+ *
+ * \return This returns the payload of the information element as a string.
+ */
+const char *ast_event_iterator_get_ie_str(struct ast_event_iterator *iterator);
+
+/*!
+ * \brief Get the value of the current IE in the iterator instance that has a raw payload
+ *
+ * \param iterator The iterator instance
+ *
+ * \return This returns the payload of the information element as type raw.
+ */
+void *ast_event_iterator_get_ie_raw(struct ast_event_iterator *iterator);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* AST_EVENT_H */
diff --git a/trunk/include/asterisk/event_defs.h b/trunk/include/asterisk/event_defs.h
new file mode 100644
index 000000000..b664ac14b
--- /dev/null
+++ b/trunk/include/asterisk/event_defs.h
@@ -0,0 +1,143 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2007, Digium, Inc.
+ *
+ * Russell Bryant <russell@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*!
+ * \file
+ * \author Russell Bryant <russell@digium.com>
+ * \brief Generic event system
+ */
+
+#ifndef AST_EVENT_DEFS_H
+#define AST_EVENT_DEFS_H
+
+/*! \brief Event types
+ * \note These values can *never* change. */
+enum ast_event_type {
+ /*! Reserved to provide the ability to subscribe to all events. A specific
+ event should never have a payload of 0. */
+ AST_EVENT_ALL = 0x00,
+ /*! This event type is reserved for use by third-party modules to create
+ custom events without having to modify this file.
+ \note There are no "custom" IE types, because IEs only have to be
+ unique to the event itself, not necessarily across all events. */
+ AST_EVENT_CUSTOM = 0x01,
+ /*! Voicemail message waiting indication */
+ AST_EVENT_MWI = 0x02,
+ /*! Someone has subscribed to events */
+ AST_EVENT_SUB = 0x03,
+ /*! Someone has unsubscribed from events */
+ AST_EVENT_UNSUB = 0x04,
+ /*! The state of a device has changed */
+ AST_EVENT_DEVICE_STATE = 0x05,
+ /*! Number of event types. This should be the last event type + 1 */
+ AST_EVENT_TOTAL = 0x06,
+};
+
+/*! \brief Event Information Element types */
+enum ast_event_ie_type {
+ /*! Used to terminate the arguments to event functions */
+ AST_EVENT_IE_END = -1,
+
+ /*!
+ * \brief Number of new messages
+ * Used by: AST_EVENT_MWI
+ * Payload type: UINT
+ */
+ AST_EVENT_IE_NEWMSGS = 0x01,
+ /*!
+ * \brief Number of
+ * Used by: AST_EVENT_MWI
+ * Payload type: UINT
+ */
+ AST_EVENT_IE_OLDMSGS = 0x02,
+ /*!
+ * \brief Mailbox name \verbatim (mailbox[@context]) \endverbatim
+ * Used by: AST_EVENT_MWI
+ * Payload type: STR
+ */
+ AST_EVENT_IE_MAILBOX = 0x03,
+ /*!
+ * \brief Unique ID
+ * Used by: AST_EVENT_SUB, AST_EVENT_UNSUB
+ * Payload type: UINT
+ */
+ AST_EVENT_IE_UNIQUEID = 0x04,
+ /*!
+ * \brief Event type
+ * Used by: AST_EVENT_SUB, AST_EVENT_UNSUB
+ * Payload type: UINT
+ */
+ AST_EVENT_IE_EVENTTYPE = 0x05,
+ /*!
+ * \brief Hint that someone cares that an IE exists
+ * Used by: AST_EVENT_SUB
+ * Payload type: UINT (ast_event_ie_type)
+ */
+ AST_EVENT_IE_EXISTS = 0x06,
+ /*!
+ * \brief Device Name
+ * Used by AST_EVENT_DEVICE_STATE
+ * Payload type: STR
+ */
+ AST_EVENT_IE_DEVICE = 0x07,
+ /*!
+ * \brief Generic State IE
+ * Used by AST_EVENT_DEVICE_STATE
+ * Payload type: UINT
+ * The actual state values depend on the event which
+ * this IE is a part of.
+ */
+ AST_EVENT_IE_STATE = 0x08,
+ /*!
+ * \brief Context IE
+ * Used by AST_EVENT_MWI
+ * Payload type: str
+ */
+ AST_EVENT_IE_CONTEXT = 0x09,
+};
+
+/*!
+ * \brief Payload types for event information elements
+ */
+enum ast_event_ie_pltype {
+ /*! Just check if it exists, not the value */
+ AST_EVENT_IE_PLTYPE_EXISTS,
+ /*! Unsigned Integer (Can be used for signed, too ...) */
+ AST_EVENT_IE_PLTYPE_UINT,
+ /*! String */
+ AST_EVENT_IE_PLTYPE_STR,
+};
+
+/*!
+ * \brief Results for checking for subscribers
+ *
+ * \ref ast_event_check_subscriber()
+ */
+enum ast_event_subscriber_res {
+ /*! No subscribers exist */
+ AST_EVENT_SUB_NONE,
+ /*! At least one subscriber exists */
+ AST_EVENT_SUB_EXISTS,
+};
+
+struct ast_event;
+struct ast_event_ie;
+struct ast_event_sub;
+struct ast_event_iterator;
+
+#endif /* AST_EVENT_DEFS_H */
diff --git a/trunk/include/asterisk/extconf.h b/trunk/include/asterisk/extconf.h
new file mode 100644
index 000000000..943945031
--- /dev/null
+++ b/trunk/include/asterisk/extconf.h
@@ -0,0 +1,248 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2007, Digium, Inc.
+ *
+ * Steve Murphy <murf@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+/*! \file External configuration handlers (realtime and static configuration)
+ * \author Steve Murphy <murf@digium.com>
+ *
+ */
+
+#ifndef _ASTERISK_EXTCONF_H
+#define _ASTERISK_EXTCONF_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+#ifdef NOTYET
+/* I'm going to define all the structs mentioned below, to avoid
+ possible conflicts in declarations that might be introduced,
+ if we just include the files that define them-- this may be
+ unnecessary */
+
+struct ast_comment {
+ struct ast_comment *next;
+ char cmt[0];
+};
+
+struct ast_variable {
+ char *name;
+ char *value;
+ int lineno;
+ int object; /*!< 0 for variable, 1 for object */
+ int blanklines; /*!< Number of blanklines following entry */
+ struct ast_comment *precomments;
+ struct ast_comment *sameline;
+ struct ast_variable *next;
+ char stuff[0];
+};
+
+struct ast_category {
+ char name[80];
+ int ignored; /*!< do not let user of the config see this category */
+ int include_level;
+ struct ast_comment *precomments;
+ struct ast_comment *sameline;
+ struct ast_variable *root;
+ struct ast_variable *last;
+ struct ast_category *next;
+};
+
+struct ast_config {
+ struct ast_category *root;
+ struct ast_category *last;
+ struct ast_category *current;
+ struct ast_category *last_browse; /*!< used to cache the last category supplied via category_browse */
+ int include_level;
+ int max_include_level;
+};
+
+/* ================== above: the config world; below, the dialplan world */
+
+/*! \brief A registered application */
+struct ast_app {
+ int (*execute)(struct ast_channel *chan, void *data);
+ const char *synopsis; /*!< Synopsis text for 'show applications' */
+ const char *description; /*!< Description (help text) for 'show application &lt;name&gt;' */
+ AST_RWLIST_ENTRY(ast_app) list; /*!< Next app in list */
+ void *module; /*!< Module this app belongs to */
+ char name[0]; /*!< Name of the application */
+};
+/*!
+ \brief An extension
+ The dialplan is saved as a linked list with each context
+ having it's own linked list of extensions - one item per
+ priority.
+*/
+struct ast_exten {
+ char *exten; /*!< Extension name */
+ int matchcid; /*!< Match caller id ? */
+ const char *cidmatch; /*!< Caller id to match for this extension */
+ int priority; /*!< Priority */
+ const char *label; /*!< Label */
+ struct ast_context *parent; /*!< The context this extension belongs to */
+ const char *app; /*!< Application to execute */
+ struct ast_app *cached_app; /*!< Cached location of application */
+ void *data; /*!< Data to use (arguments) */
+ void (*datad)(void *); /*!< Data destructor */
+ struct ast_exten *peer; /*!< Next higher priority with our extension */
+ const char *registrar; /*!< Registrar */
+ struct ast_exten *next; /*!< Extension with a greater ID */
+ char stuff[0];
+};
+/* from pbx.h */
+typedef int (*ast_state_cb_type)(char *context, char* id, enum ast_extension_states state, void *data);
+struct ast_timing {
+ int hastime; /*!< If time construct exists */
+ unsigned int monthmask; /*!< Mask for month */
+ unsigned int daymask; /*!< Mask for date */
+ unsigned int dowmask; /*!< Mask for day of week (mon-sun) */
+ unsigned int minmask[24]; /*!< Mask for minute */
+};
+/*! \brief include= support in extensions.conf */
+struct ast_include {
+ const char *name;
+ const char *rname; /*!< Context to include */
+ const char *registrar; /*!< Registrar */
+ int hastime; /*!< If time construct exists */
+ struct ast_timing timing; /*!< time construct */
+ struct ast_include *next; /*!< Link them together */
+ char stuff[0];
+};
+
+/*! \brief Switch statement in extensions.conf */
+struct ast_sw {
+ char *name;
+ const char *registrar; /*!< Registrar */
+ char *data; /*!< Data load */
+ int eval;
+ AST_LIST_ENTRY(ast_sw) list;
+ char *tmpdata;
+ char stuff[0];
+};
+
+*! \brief Ignore patterns in dial plan */
+struct ast_ignorepat {
+ const char *registrar;
+ struct ast_ignorepat *next;
+ const char pattern[0];
+};
+
+/*! \brief An extension context */
+struct ast_context {
+ ast_rwlock_t lock; /*!< A lock to prevent multiple threads from clobbering the context */
+ struct ast_exten *root; /*!< The root of the list of extensions */
+ struct ast_context *next; /*!< Link them together */
+ struct ast_include *includes; /*!< Include other contexts */
+ struct ast_ignorepat *ignorepats; /*!< Patterns for which to continue playing dialtone */
+ const char *registrar; /*!< Registrar */
+ AST_LIST_HEAD_NOLOCK(, ast_sw) alts; /*!< Alternative switches */
+ ast_mutex_t macrolock; /*!< A lock to implement "exclusive" macros - held whilst a call is executing in the macro */
+ char name[0]; /*!< Name of the context */
+};
+
+#endif
+
+struct ast_config *localized_config_load(const char *filename);
+struct ast_config *localized_config_load_with_comments(const char *filename);
+struct ast_category *localized_category_get(const struct ast_config *config, const char *category_name);
+int localized_config_text_file_save(const char *configfile, const struct ast_config *cfg, const char *generator);
+struct ast_context *localized_walk_contexts(struct ast_context *con);
+struct ast_exten *localized_walk_context_extensions(struct ast_context *con,
+ struct ast_exten *exten);
+struct ast_exten *localized_walk_extension_priorities(struct ast_exten *exten,
+ struct ast_exten *priority);
+struct ast_include *localized_walk_context_includes(struct ast_context *con,
+ struct ast_include *inc);
+struct ast_sw *localized_walk_context_switches(struct ast_context *con,
+ struct ast_sw *sw);
+
+void localized_context_destroy(struct ast_context *con, const char *registrar);
+int localized_pbx_load_module(void);
+
+struct ast_context *localized_context_create(struct ast_context **extcontexts, const char *name, const char *registrar);
+int localized_pbx_builtin_setvar(struct ast_channel *chan, void *data);
+int localized_context_add_ignorepat2(struct ast_context *con, const char *value, const char *registrar);
+int localized_context_add_switch2(struct ast_context *con, const char *value,
+ const char *data, int eval, const char *registrar);
+int localized_context_add_include2(struct ast_context *con, const char *value,
+ const char *registrar);
+int localized_add_extension2(struct ast_context *con,
+ int replace, const char *extension, int priority, const char *label, const char *callerid,
+ const char *application, void *data, void (*datad)(void *),
+ const char *registrar);
+void localized_merge_contexts_and_delete(struct ast_context **extcontexts, const char *registrar);
+int localized_context_verify_includes(struct ast_context *con);
+void localized_use_conf_dir(void);
+void localized_use_local_dir(void);
+
+
+#ifndef _ASTERISK_PBX_H
+/*!
+ * When looking up extensions, we can have different requests
+ * identified by the 'action' argument, as follows.
+ * Note that the coding is such that the low 4 bits are the
+ * third argument to extension_match_core.
+ */
+enum ext_match_t {
+ E_MATCHMORE = 0x00, /* extension can match but only with more 'digits' */
+ E_CANMATCH = 0x01, /* extension can match with or without more 'digits' */
+ E_MATCH = 0x02, /* extension is an exact match */
+ E_MATCH_MASK = 0x03, /* mask for the argument to extension_match_core() */
+ E_SPAWN = 0x12, /* want to spawn an extension. Requires exact match */
+ E_FINDLABEL = 0x22 /* returns the priority for a given label. Requires exact match */
+};
+#define AST_PBX_MAX_STACK 128
+
+/* request and result for pbx_find_extension */
+struct pbx_find_info {
+#if 0
+ const char *context;
+ const char *exten;
+ int priority;
+#endif
+
+ char *incstack[AST_PBX_MAX_STACK]; /* filled during the search */
+ int stacklen; /* modified during the search */
+ int status; /* set on return */
+ struct ast_switch *swo; /* set on return */
+ const char *data; /* set on return */
+ const char *foundcontext; /* set on return */
+};
+
+#define STATUS_NO_CONTEXT 1
+#define STATUS_NO_EXTENSION 2
+#define STATUS_NO_PRIORITY 3
+#define STATUS_NO_LABEL 4
+#define STATUS_SUCCESS 5
+
+#endif
+
+struct ast_exten *localized_find_extension(struct ast_context *bypass,
+ struct pbx_find_info *q,
+ const char *context,
+ const char *exten,
+ int priority,
+ const char *label,
+ const char *callerid,
+ enum ext_match_t action);
+
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _ASTERISK_PBX_H */
diff --git a/trunk/include/asterisk/features.h b/trunk/include/asterisk/features.h
new file mode 100644
index 000000000..aa145a961
--- /dev/null
+++ b/trunk/include/asterisk/features.h
@@ -0,0 +1,112 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2005, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief Call Parking and Pickup API
+ * Includes code and algorithms from the Zapata library.
+ */
+
+#ifndef _AST_FEATURES_H
+#define _AST_FEATURES_H
+
+#define FEATURE_MAX_LEN 11
+#define FEATURE_APP_LEN 64
+#define FEATURE_APP_ARGS_LEN 256
+#define FEATURE_SNAME_LEN 32
+#define FEATURE_EXTEN_LEN 32
+#define FEATURE_MOH_LEN 80 /* same as MAX_MUSICCLASS from channel.h */
+
+/*! \brief main call feature structure */
+struct ast_call_feature {
+ int feature_mask;
+ char *fname;
+ char sname[FEATURE_SNAME_LEN];
+ char exten[FEATURE_MAX_LEN];
+ char default_exten[FEATURE_MAX_LEN];
+ int (*operation)(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config, char *code, int sense, void *data);
+ unsigned int flags;
+ char app[FEATURE_APP_LEN];
+ char app_args[FEATURE_APP_ARGS_LEN];
+ char moh_class[FEATURE_MOH_LEN];
+ AST_LIST_ENTRY(ast_call_feature) feature_entry;
+};
+
+
+
+/*!
+ * \brief Park a call and read back parked location
+ * \param chan the channel to actually be parked
+ * \param host the channel which will have the parked location read to.
+ * \param timeout is a timeout in milliseconds
+ * \param extout is a parameter to an int that will hold the parked location, or NULL if you want.
+ *
+ * Park the channel chan, and read back the parked location to the host.
+ * If the call is not picked up within a specified period of time,
+ * then the call will return to the last step that it was in
+ * (in terms of exten, priority and context)
+ * \retval 0 on success.
+ * \retval -1 on failure.
+*/
+int ast_park_call(struct ast_channel *chan, struct ast_channel *host, int timeout, int *extout);
+
+/*!
+ * \brief Park a call via a masqueraded channel
+ * \param rchan the real channel to be parked
+ * \param host the channel to have the parking read to.
+ * \param timeout is a timeout in milliseconds
+ * \param extout is a parameter to an int that will hold the parked location, or NULL if you want.
+ *
+ * Masquerade the channel rchan into a new, empty channel which is then parked with ast_park_call
+ * \retval 0 on success.
+ * \retval -1 on failure.
+*/
+int ast_masq_park_call(struct ast_channel *rchan, struct ast_channel *host, int timeout, int *extout);
+
+/*!
+ * \brief Determine system parking extension
+ * \returns the call parking extension for drivers that provide special call parking help
+*/
+const char *ast_parking_ext(void);
+
+/*! \brief Determine system call pickup extension */
+const char *ast_pickup_ext(void);
+
+/*! \brief Bridge a call, optionally allowing redirection */
+int ast_bridge_call(struct ast_channel *chan, struct ast_channel *peer,struct ast_bridge_config *config);
+
+/*! \brief Pickup a call */
+int ast_pickup_call(struct ast_channel *chan);
+
+/*! \brief register new feature into feature_set
+ \param feature an ast_call_feature object which contains a keysequence
+ and a callback function which is called when this keysequence is pressed
+ during a call. */
+void ast_register_feature(struct ast_call_feature *feature);
+
+/*! \brief unregister feature from feature_set
+ \param feature the ast_call_feature object which was registered before*/
+void ast_unregister_feature(struct ast_call_feature *feature);
+
+/*! \brief look for a call feature entry by its sname
+ \param name a string ptr, should match "automon", "blindxfer", "atxfer", etc. */
+struct ast_call_feature *ast_find_call_feature(const char *name);
+
+void ast_rdlock_call_features(void);
+void ast_unlock_call_features(void);
+
+#endif /* _AST_FEATURES_H */
diff --git a/trunk/include/asterisk/file.h b/trunk/include/asterisk/file.h
new file mode 100644
index 000000000..0f33b5340
--- /dev/null
+++ b/trunk/include/asterisk/file.h
@@ -0,0 +1,322 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2006, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief Generic File Format Support.
+ * Should be included by clients of the file handling routines.
+ * File service providers should instead include mod_format.h
+ */
+
+#ifndef _ASTERISK_FILE_H
+#define _ASTERISK_FILE_H
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#ifdef HAVE_MMAP
+#include <sys/mman.h>
+#endif
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+struct ast_filestream;
+struct ast_format;
+
+/*! Convenient for waiting */
+#define AST_DIGIT_ANY "0123456789#*ABCD"
+#define AST_DIGIT_ANYNUM "0123456789"
+
+#define SEEK_FORCECUR 10
+
+/*!
+ * \brief Streams a file
+ * \param c channel to stream the file to
+ * \param filename the name of the file you wish to stream, minus the extension
+ * \param preflang the preferred language you wish to have the file streamed to you in
+ * Prepares a channel for the streaming of a file. To start the stream, afterward do a ast_waitstream() on the channel
+ * Also, it will stop any existing streams on the channel.
+ * \retval 0 on success.
+ * \retval -1 on failure.
+ */
+int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang);
+
+/*!
+ * \brief stream file until digit
+ * If the file name is non-empty, try to play it.
+ * \note If digits == "" then we can simply check for non-zero.
+ * \return 0 if success.
+ * \retval -1 if error.
+ * \retval digit if interrupted by a digit.
+ */
+int ast_stream_and_wait(struct ast_channel *chan, const char *file, const char *digits);
+
+/*!
+ * \brief Stops a stream
+ *
+ * \param c The channel you wish to stop playback on
+ *
+ * Stop playback of a stream
+ *
+ * \retval 0 always
+ *
+ * \note The channel does not need to be locked before calling this function.
+ */
+int ast_stopstream(struct ast_channel *c);
+
+/*!
+ * \brief Checks for the existence of a given file
+ * \param filename name of the file you wish to check, minus the extension
+ * \param fmt the format you wish to check (the extension)
+ * \param preflang (the preferred language you wisht to find the file in)
+ * See if a given file exists in a given format. If fmt is NULL, any format is accepted.
+ * \return -1 if file does not exist, non-zero positive otherwise.
+ */
+int ast_fileexists(const char *filename, const char *fmt, const char *preflang);
+
+/*!
+ * \brief Renames a file
+ * \param oldname the name of the file you wish to act upon (minus the extension)
+ * \param newname the name you wish to rename the file to (minus the extension)
+ * \param fmt the format of the file
+ * Rename a given file in a given format, or if fmt is NULL, then do so for all
+ * \return -1 on failure
+ */
+int ast_filerename(const char *oldname, const char *newname, const char *fmt);
+
+/*!
+ * \brief Deletes a file
+ * \param filename name of the file you wish to delete (minus the extension)
+ * \param fmt of the file
+ * Delete a given file in a given format, or if fmt is NULL, then do so for all
+ */
+int ast_filedelete(const char *filename, const char *fmt);
+
+/*!
+ * \brief Copies a file
+ * \param oldname name of the file you wish to copy (minus extension)
+ * \param newname name you wish the file to be copied to (minus extension)
+ * \param fmt the format of the file
+ * Copy a given file in a given format, or if fmt is NULL, then do so for all
+ */
+int ast_filecopy(const char *oldname, const char *newname, const char *fmt);
+
+/*!
+ * \brief Waits for a stream to stop or digit to be pressed
+ * \param c channel to waitstream on
+ * \param breakon string of DTMF digits to break upon
+ * Begins playback of a stream...
+ * Wait for a stream to stop or for any one of a given digit to arrive,
+ * \retval 0 if the stream finishes
+ * \retval the character if it was interrupted,
+ * \retval -1 on error
+ */
+int ast_waitstream(struct ast_channel *c, const char *breakon);
+
+/*!
+ * \brief Waits for a stream to stop or digit matching a valid one digit exten to be pressed
+ * \param c channel to waitstream on
+ * \param context string of context to match digits to break upon
+ * Begins playback of a stream...
+ * Wait for a stream to stop or for any one of a valid extension digit to arrive,
+ * \retval 0 if the stream finishes.
+ * \retval the character if it was interrupted.
+ * \retval -1 on error.
+ */
+int ast_waitstream_exten(struct ast_channel *c, const char *context);
+
+/*!
+ * \brief Same as waitstream but allows stream to be forwarded or rewound
+ * \param c channel to waitstream on
+ * \param breakon string of DTMF digits to break upon
+ * \param forward DTMF digit to fast forward upon
+ * \param rewind DTMF digit to rewind upon
+ * \param ms How many miliseconds to skip forward/back
+ * Begins playback of a stream...
+ * Wait for a stream to stop or for any one of a given digit to arrive,
+ * \retval 0 if the stream finishes.
+ * \retval the character if it was interrupted.
+ * \retval -1 on error.
+ */
+int ast_waitstream_fr(struct ast_channel *c, const char *breakon, const char *forward, const char *rewind, int ms);
+
+/*!
+ * Same as waitstream, but with audio output to fd and monitored fd checking.
+ *
+ * \return 1 if monfd is ready for reading
+ */
+int ast_waitstream_full(struct ast_channel *c, const char *breakon, int audiofd, int monfd);
+
+/*!
+ * \brief Starts reading from a file
+ * \param filename the name of the file to read from
+ * \param type format of file you wish to read from
+ * \param comment comment to go with
+ * \param flags file flags
+ * \param check (unimplemented, hence negligible)
+ * \param mode Open mode
+ * Open an incoming file stream. flags are flags for the open() command, and
+ * if check is non-zero, then it will not read a file if there are any files that
+ * start with that name and have an extension
+ * Please note, this is a blocking function. Program execution will not return until ast_waitstream completes it's execution.
+ * \retval a struct ast_filestream on success.
+ * \retval NULL on failure.
+ */
+struct ast_filestream *ast_readfile(const char *filename, const char *type, const char *comment, int flags, int check, mode_t mode);
+
+/*!
+ * \brief Starts writing a file
+ * \param filename the name of the file to write to
+ * \param type format of file you wish to write out to
+ * \param comment comment to go with
+ * \param flags output file flags
+ * \param check (unimplemented, hence negligible)
+ * \param mode Open mode
+ * Create an outgoing file stream. oflags are flags for the open() command, and
+ * if check is non-zero, then it will not write a file if there are any files that
+ * start with that name and have an extension
+ * Please note, this is a blocking function. Program execution will not return until ast_waitstream completes it's execution.
+ * \retval a struct ast_filestream on success.
+ * \retval NULL on failure.
+ */
+struct ast_filestream *ast_writefile(const char *filename, const char *type, const char *comment, int flags, int check, mode_t mode);
+
+/*!
+ * \brief Writes a frame to a stream
+ * \param fs filestream to write to
+ * \param f frame to write to the filestream
+ * Send a frame to a filestream -- note: does NOT free the frame, call ast_frfree manually
+ * \retval 0 on success.
+ * \retval -1 on failure.
+ */
+int ast_writestream(struct ast_filestream *fs, struct ast_frame *f);
+
+/*!
+ * \brief Closes a stream
+ * \param f filestream to close
+ * Close a playback or recording stream
+ * \retval 0 on success.
+ * \retval -1 on failure.
+ */
+int ast_closestream(struct ast_filestream *f);
+
+/*!
+ * \brief Opens stream for use in seeking, playing
+ * \param chan channel to work with
+ * \param filename to use
+ * \param preflang prefered language to use
+ * \retval a ast_filestream pointer if it opens the file.
+ * \retval NULL on error.
+ */
+struct ast_filestream *ast_openstream(struct ast_channel *chan, const char *filename, const char *preflang);
+
+/*!
+ * \brief Opens stream for use in seeking, playing
+ * \param chan channel to work with
+ * \param filename to use
+ * \param preflang prefered language to use
+ * \param asis if set, don't clear generators
+ * \retval a ast_filestream pointer if it opens the file.
+ * \retval NULL on error.
+ */
+struct ast_filestream *ast_openstream_full(struct ast_channel *chan, const char *filename, const char *preflang, int asis);
+/*!
+ * \brief Opens stream for use in seeking, playing
+ * \param chan channel to work with
+ * \param filename to use
+ * \param preflang prefered language to use
+ * \retval a ast_filestream pointer if it opens the file.
+ * \retval NULL on error.
+ */
+struct ast_filestream *ast_openvstream(struct ast_channel *chan, const char *filename, const char *preflang);
+
+/*!
+ * \brief Applys a open stream to a channel.
+ * \param chan channel to work
+ * \param s ast_filestream to apply
+ * \retval 0 on success.
+ * \retval -1 on failure.
+ */
+int ast_applystream(struct ast_channel *chan, struct ast_filestream *s);
+
+/*!
+ * \brief Play a open stream on a channel.
+ * \param s filestream to play
+ * \retval 0 on success.
+ * \retval -1 on failure.
+ */
+int ast_playstream(struct ast_filestream *s);
+
+/*!
+ * \brief Seeks into stream
+ * \param fs ast_filestream to perform seek on
+ * \param sample_offset numbers of samples to seek
+ * \param whence SEEK_SET, SEEK_CUR, SEEK_END
+ * \retval 0 on success.
+ * \retval -1 on failure.
+ */
+int ast_seekstream(struct ast_filestream *fs, off_t sample_offset, int whence);
+
+/*!
+ * \brief Trunc stream at current location
+ * \param fs filestream to act on
+ * \retval 0 on success.
+ * \retval -1 on failure.
+ */
+int ast_truncstream(struct ast_filestream *fs);
+
+/*!
+ * \brief Fast forward stream ms
+ * \param fs filestream to act on
+ * \param ms milliseconds to move
+ * \retval 0 on success.
+ * \retval -1 on failure.
+ */
+int ast_stream_fastforward(struct ast_filestream *fs, off_t ms);
+
+/*!
+ * \brief Rewind stream ms
+ * \param fs filestream to act on
+ * \param ms milliseconds to move
+ * \retval 0 on success.
+ * \retval -1 on failure.
+ */
+int ast_stream_rewind(struct ast_filestream *fs, off_t ms);
+
+/*!
+ * \brief Tell where we are in a stream
+ * \param fs fs to act on
+ * \return a long as a sample offset into stream
+ */
+off_t ast_tellstream(struct ast_filestream *fs);
+
+/*!
+ * \brief Read a frame from a filestream
+ * \param s ast_filestream to act on
+ * \return a frame.
+ * \retval NULL if read failed.
+ */
+struct ast_frame *ast_readframe(struct ast_filestream *s);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _ASTERISK_FILE_H */
diff --git a/trunk/include/asterisk/frame.h b/trunk/include/asterisk/frame.h
new file mode 100644
index 000000000..3983c84cf
--- /dev/null
+++ b/trunk/include/asterisk/frame.h
@@ -0,0 +1,603 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2005, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief Asterisk internal frame definitions.
+ * \arg For an explanation of frames, see \ref Def_Frame
+ * \arg Frames are send of Asterisk channels, see \ref Def_Channel
+ */
+
+#ifndef _ASTERISK_FRAME_H
+#define _ASTERISK_FRAME_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+#include <sys/time.h>
+
+#include "asterisk/endian.h"
+#include "asterisk/linkedlists.h"
+
+struct ast_codec_pref {
+ char order[32];
+ char framing[32];
+};
+
+/*! \page Def_Frame AST Multimedia and signalling frames
+ \section Def_AstFrame What is an ast_frame ?
+ A frame of data read used to communicate between
+ between channels and applications.
+ Frames are divided into frame types and subclasses.
+
+ \par Frame types
+ \arg \b VOICE: Voice data, subclass is codec (AST_FORMAT_*)
+ \arg \b VIDEO: Video data, subclass is codec (AST_FORMAT_*)
+ \arg \b DTMF: A DTMF digit, subclass is the digit
+ \arg \b IMAGE: Image transport, mostly used in IAX
+ \arg \b TEXT: Text messages and character by character (real time text)
+ \arg \b HTML: URL's and web pages
+ \arg \b MODEM: Modulated data encodings, such as T.38 and V.150
+ \arg \b IAX: Private frame type for the IAX protocol
+ \arg \b CNG: Comfort noice frames
+ \arg \b CONTROL: A control frame, subclass defined as AST_CONTROL_
+ \arg \b NULL: Empty, useless frame
+
+ \par Files
+ \arg frame.h Definitions
+ \arg frame.c Function library
+ \arg \ref Def_Channel Asterisk channels
+ \section Def_ControlFrame Control Frames
+ Control frames send signalling information between channels
+ and devices. They are prefixed with AST_CONTROL_, like AST_CONTROL_FRAME_HANGUP
+ \arg \b HANGUP The other end has hungup
+ \arg \b RING Local ring
+ \arg \b RINGING The other end is ringing
+ \arg \b ANSWER The other end has answered
+ \arg \b BUSY Remote end is busy
+ \arg \b TAKEOFFHOOK Make it go off hook (what's "it" ? )
+ \arg \b OFFHOOK Line is off hook
+ \arg \b CONGESTION Congestion (circuit is busy, not available)
+ \arg \b FLASH Other end sends flash hook
+ \arg \b WINK Other end sends wink
+ \arg \b OPTION Send low-level option
+ \arg \b RADIO_KEY Key radio (see app_rpt.c)
+ \arg \b RADIO_UNKEY Un-key radio (see app_rpt.c)
+ \arg \b PROGRESS Other end indicates call progress
+ \arg \b PROCEEDING Indicates proceeding
+ \arg \b HOLD Call is placed on hold
+ \arg \b UNHOLD Call is back from hold
+ \arg \b VIDUPDATE Video update requested
+
+*/
+
+/*!
+ * \brief Frame types
+ *
+ * \note It is important that the values of each frame type are never changed,
+ * because it will break backwards compatability with older versions.
+ * This is because these constants are transmitted directly over IAX2.
+ */
+enum ast_frame_type {
+ /*! DTMF end event, subclass is the digit */
+ AST_FRAME_DTMF_END = 1,
+ /*! Voice data, subclass is AST_FORMAT_* */
+ AST_FRAME_VOICE,
+ /*! Video frame, maybe?? :) */
+ AST_FRAME_VIDEO,
+ /*! A control frame, subclass is AST_CONTROL_* */
+ AST_FRAME_CONTROL,
+ /*! An empty, useless frame */
+ AST_FRAME_NULL,
+ /*! Inter Asterisk Exchange private frame type */
+ AST_FRAME_IAX,
+ /*! Text messages */
+ AST_FRAME_TEXT,
+ /*! Image Frames */
+ AST_FRAME_IMAGE,
+ /*! HTML Frame */
+ AST_FRAME_HTML,
+ /*! Comfort Noise frame (subclass is level of CNG in -dBov),
+ body may include zero or more 8-bit quantization coefficients */
+ AST_FRAME_CNG,
+ /*! Modem-over-IP data streams */
+ AST_FRAME_MODEM,
+ /*! DTMF begin event, subclass is the digit */
+ AST_FRAME_DTMF_BEGIN,
+};
+#define AST_FRAME_DTMF AST_FRAME_DTMF_END
+
+enum {
+ /*! This frame contains valid timing information */
+ AST_FRFLAG_HAS_TIMING_INFO = (1 << 0),
+ /*! This frame came from a translator and is still the original frame.
+ * The translator can not be free'd if the frame inside of it still has
+ * this flag set. */
+ AST_FRFLAG_FROM_TRANSLATOR = (1 << 1),
+};
+
+/*! \brief Data structure associated with a single frame of data
+ */
+struct ast_frame {
+ /*! Kind of frame */
+ enum ast_frame_type frametype;
+ /*! Subclass, frame dependent */
+ int subclass;
+ /*! Length of data */
+ int datalen;
+ /*! Number of 8khz samples in this frame */
+ int samples;
+ /*! Was the data malloc'd? i.e. should we free it when we discard the frame? */
+ int mallocd;
+ /*! The number of bytes allocated for a malloc'd frame header */
+ size_t mallocd_hdr_len;
+ /*! How many bytes exist _before_ "data" that can be used if needed */
+ int offset;
+ /*! Optional source of frame for debugging */
+ const char *src;
+ /*! Pointer to actual data */
+ void *data;
+ /*! Global delivery time */
+ struct timeval delivery;
+ /*! For placing in a linked list */
+ AST_LIST_ENTRY(ast_frame) frame_list;
+ /*! Misc. frame flags */
+ unsigned int flags;
+ /*! Timestamp in milliseconds */
+ long ts;
+ /*! Length in milliseconds */
+ long len;
+ /*! Sequence number */
+ int seqno;
+};
+
+/*!
+ * Set the various field of a frame to point to a buffer.
+ * Typically you set the base address of the buffer, the offset as
+ * AST_FRIENDLY_OFFSET, and the datalen as the amount of bytes queued.
+ * The remaining things (to be done manually) is set the number of
+ * samples, which cannot be derived from the datalen unless you know
+ * the number of bits per sample.
+ */
+#define AST_FRAME_SET_BUFFER(fr, _base, _ofs, _datalen) \
+ { \
+ (fr)->data = (char *)_base + (_ofs); \
+ (fr)->offset = (_ofs); \
+ (fr)->datalen = (_datalen); \
+ }
+
+/*! Queueing a null frame is fairly common, so we declare a global null frame object
+ for this purpose instead of having to declare one on the stack */
+extern struct ast_frame ast_null_frame;
+
+#define AST_FRIENDLY_OFFSET 64 /*! It's polite for a a new frame to
+ have this number of bytes for additional
+ headers. */
+#define AST_MIN_OFFSET 32 /*! Make sure we keep at least this much handy */
+
+/*! Need the header be free'd? */
+#define AST_MALLOCD_HDR (1 << 0)
+/*! Need the data be free'd? */
+#define AST_MALLOCD_DATA (1 << 1)
+/*! Need the source be free'd? (haha!) */
+#define AST_MALLOCD_SRC (1 << 2)
+
+/* MODEM subclasses */
+/*! T.38 Fax-over-IP */
+#define AST_MODEM_T38 1
+/*! V.150 Modem-over-IP */
+#define AST_MODEM_V150 2
+
+/* HTML subclasses */
+/*! Sending a URL */
+#define AST_HTML_URL 1
+/*! Data frame */
+#define AST_HTML_DATA 2
+/*! Beginning frame */
+#define AST_HTML_BEGIN 4
+/*! End frame */
+#define AST_HTML_END 8
+/*! Load is complete */
+#define AST_HTML_LDCOMPLETE 16
+/*! Peer is unable to support HTML */
+#define AST_HTML_NOSUPPORT 17
+/*! Send URL, and track */
+#define AST_HTML_LINKURL 18
+/*! No more HTML linkage */
+#define AST_HTML_UNLINK 19
+/*! Reject link request */
+#define AST_HTML_LINKREJECT 20
+
+/* Data formats for capabilities and frames alike */
+/*! G.723.1 compression */
+#define AST_FORMAT_G723_1 (1 << 0)
+/*! GSM compression */
+#define AST_FORMAT_GSM (1 << 1)
+/*! Raw mu-law data (G.711) */
+#define AST_FORMAT_ULAW (1 << 2)
+/*! Raw A-law data (G.711) */
+#define AST_FORMAT_ALAW (1 << 3)
+/*! ADPCM (G.726, 32kbps, AAL2 codeword packing) */
+#define AST_FORMAT_G726_AAL2 (1 << 4)
+/*! ADPCM (IMA) */
+#define AST_FORMAT_ADPCM (1 << 5)
+/*! Raw 16-bit Signed Linear (8000 Hz) PCM */
+#define AST_FORMAT_SLINEAR (1 << 6)
+/*! LPC10, 180 samples/frame */
+#define AST_FORMAT_LPC10 (1 << 7)
+/*! G.729A audio */
+#define AST_FORMAT_G729A (1 << 8)
+/*! SpeeX Free Compression */
+#define AST_FORMAT_SPEEX (1 << 9)
+/*! iLBC Free Compression */
+#define AST_FORMAT_ILBC (1 << 10)
+/*! ADPCM (G.726, 32kbps, RFC3551 codeword packing) */
+#define AST_FORMAT_G726 (1 << 11)
+/*! G.722 */
+#define AST_FORMAT_G722 (1 << 12)
+/*! Raw 16-bit Signed Linear (16000 Hz) PCM */
+#define AST_FORMAT_SLINEAR16 (1 << 15)
+/*! Maximum audio mask */
+#define AST_FORMAT_AUDIO_MASK ((1 << 16)-1)
+/*! JPEG Images */
+#define AST_FORMAT_JPEG (1 << 16)
+/*! PNG Images */
+#define AST_FORMAT_PNG (1 << 17)
+/*! H.261 Video */
+#define AST_FORMAT_H261 (1 << 18)
+/*! H.263 Video */
+#define AST_FORMAT_H263 (1 << 19)
+/*! H.263+ Video */
+#define AST_FORMAT_H263_PLUS (1 << 20)
+/*! H.264 Video */
+#define AST_FORMAT_H264 (1 << 21)
+/*! MPEG4 Video */
+#define AST_FORMAT_MP4_VIDEO (1 << 22)
+#define AST_FORMAT_VIDEO_MASK (((1 << 25)-1) & ~(AST_FORMAT_AUDIO_MASK))
+/*! T.140 Text format - ITU T.140, RFC 4351*/
+#define AST_FORMAT_T140 (1 << 25)
+#define AST_FORMAT_TEXT_MASK (((1 << 30)-1) & ~(AST_FORMAT_AUDIO_MASK) & ~(AST_FORMAT_VIDEO_MASK))
+
+enum ast_control_frame_type {
+ AST_CONTROL_HANGUP = 1, /*!< Other end has hungup */
+ AST_CONTROL_RING = 2, /*!< Local ring */
+ AST_CONTROL_RINGING = 3, /*!< Remote end is ringing */
+ AST_CONTROL_ANSWER = 4, /*!< Remote end has answered */
+ AST_CONTROL_BUSY = 5, /*!< Remote end is busy */
+ AST_CONTROL_TAKEOFFHOOK = 6, /*!< Make it go off hook */
+ AST_CONTROL_OFFHOOK = 7, /*!< Line is off hook */
+ AST_CONTROL_CONGESTION = 8, /*!< Congestion (circuits busy) */
+ AST_CONTROL_FLASH = 9, /*!< Flash hook */
+ AST_CONTROL_WINK = 10, /*!< Wink */
+ AST_CONTROL_OPTION = 11, /*!< Set a low-level option */
+ AST_CONTROL_RADIO_KEY = 12, /*!< Key Radio */
+ AST_CONTROL_RADIO_UNKEY = 13, /*!< Un-Key Radio */
+ AST_CONTROL_PROGRESS = 14, /*!< Indicate PROGRESS */
+ AST_CONTROL_PROCEEDING = 15, /*!< Indicate CALL PROCEEDING */
+ AST_CONTROL_HOLD = 16, /*!< Indicate call is placed on hold */
+ AST_CONTROL_UNHOLD = 17, /*!< Indicate call is left from hold */
+ AST_CONTROL_VIDUPDATE = 18, /*!< Indicate video frame update */
+};
+
+#define AST_SMOOTHER_FLAG_G729 (1 << 0)
+#define AST_SMOOTHER_FLAG_BE (1 << 1)
+
+/* Option identifiers and flags */
+#define AST_OPTION_FLAG_REQUEST 0
+#define AST_OPTION_FLAG_ACCEPT 1
+#define AST_OPTION_FLAG_REJECT 2
+#define AST_OPTION_FLAG_QUERY 4
+#define AST_OPTION_FLAG_ANSWER 5
+#define AST_OPTION_FLAG_WTF 6
+
+/*! Verify touchtones by muting audio transmission
+ (and reception) and verify the tone is still present */
+#define AST_OPTION_TONE_VERIFY 1
+
+/*! Put a compatible channel into TDD (TTY for the hearing-impared) mode */
+#define AST_OPTION_TDD 2
+
+/*! Relax the parameters for DTMF reception (mainly for radio use) */
+#define AST_OPTION_RELAXDTMF 3
+
+/*! Set (or clear) Audio (Not-Clear) Mode */
+#define AST_OPTION_AUDIO_MODE 4
+
+/*! Set channel transmit gain
+ * Option data is a single signed char
+ representing number of decibels (dB)
+ to set gain to (on top of any gain
+ specified in channel driver)
+*/
+#define AST_OPTION_TXGAIN 5
+
+/*! Set channel receive gain
+ * Option data is a single signed char
+ representing number of decibels (dB)
+ to set gain to (on top of any gain
+ specified in channel driver)
+*/
+#define AST_OPTION_RXGAIN 6
+
+/* set channel into "Operator Services" mode */
+#define AST_OPTION_OPRMODE 7
+
+/*! Explicitly enable or disable echo cancelation for the given channel */
+#define AST_OPTION_ECHOCAN 8
+
+struct oprmode {
+ struct ast_channel *peer;
+ int mode;
+} ;
+
+struct ast_option_header {
+ /* Always keep in network byte order */
+#if __BYTE_ORDER == __BIG_ENDIAN
+ uint16_t flag:3;
+ uint16_t option:13;
+#else
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ uint16_t option:13;
+ uint16_t flag:3;
+#else
+#error Byte order not defined
+#endif
+#endif
+ uint8_t data[0];
+};
+
+
+/*! \brief Definition of supported media formats (codecs) */
+struct ast_format_list {
+ int bits; /*!< bitmask value */
+ char *name; /*!< short name */
+ int samplespersecond; /*!< Number of samples per second (8000/16000) */
+ char *desc; /*!< Description */
+ int fr_len; /*!< Single frame length in bytes */
+ int min_ms; /*!< Min value */
+ int max_ms; /*!< Max value */
+ int inc_ms; /*!< Increment */
+ int def_ms; /*!< Default value */
+ unsigned int flags; /*!< Smoother flags */
+ int cur_ms; /*!< Current value */
+};
+
+
+/*! \brief Requests a frame to be allocated
+ *
+ * \param source
+ * Request a frame be allocated. source is an optional source of the frame,
+ * len is the requested length, or "0" if the caller will supply the buffer
+ */
+#if 0 /* Unimplemented */
+struct ast_frame *ast_fralloc(char *source, int len);
+#endif
+
+/*!
+ * \brief Frees a frame
+ *
+ * \param fr Frame to free
+ * \param cache Whether to consider this frame for frame caching
+ */
+void ast_frame_free(struct ast_frame *fr, int cache);
+
+#define ast_frfree(fr) ast_frame_free(fr, 1)
+
+/*! \brief Makes a frame independent of any static storage
+ * \param fr frame to act upon
+ * Take a frame, and if it's not been malloc'd, make a malloc'd copy
+ * and if the data hasn't been malloced then make the
+ * data malloc'd. If you need to store frames, say for queueing, then
+ * you should call this function.
+ * \return Returns a frame on success, NULL on error
+ */
+struct ast_frame *ast_frisolate(struct ast_frame *fr);
+
+/*! \brief Copies a frame
+ * \param fr frame to copy
+ * Duplicates a frame -- should only rarely be used, typically frisolate is good enough
+ * \return Returns a frame on success, NULL on error
+ */
+struct ast_frame *ast_frdup(const struct ast_frame *fr);
+
+void ast_swapcopy_samples(void *dst, const void *src, int samples);
+
+/* Helpers for byteswapping native samples to/from
+ little-endian and big-endian. */
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define ast_frame_byteswap_le(fr) do { ; } while(0)
+#define ast_frame_byteswap_be(fr) do { struct ast_frame *__f = (fr); ast_swapcopy_samples(__f->data, __f->data, __f->samples); } while(0)
+#else
+#define ast_frame_byteswap_le(fr) do { struct ast_frame *__f = (fr); ast_swapcopy_samples(__f->data, __f->data, __f->samples); } while(0)
+#define ast_frame_byteswap_be(fr) do { ; } while(0)
+#endif
+
+
+/*! \brief Get the name of a format
+ * \param format id of format
+ * \return A static string containing the name of the format or "unknown" if unknown.
+ */
+char* ast_getformatname(int format);
+
+/*! \brief Get the names of a set of formats
+ * \param buf a buffer for the output string
+ * \param size size of buf (bytes)
+ * \param format the format (combined IDs of codecs)
+ * Prints a list of readable codec names corresponding to "format".
+ * ex: for format=AST_FORMAT_GSM|AST_FORMAT_SPEEX|AST_FORMAT_ILBC it will return "0x602 (GSM|SPEEX|ILBC)"
+ * \return The return value is buf.
+ */
+char* ast_getformatname_multiple(char *buf, size_t size, int format);
+
+/*!
+ * \brief Gets a format from a name.
+ * \param name string of format
+ * \return This returns the form of the format in binary on success, 0 on error.
+ */
+int ast_getformatbyname(const char *name);
+
+/*! \brief Get a name from a format
+ * Gets a name from a format
+ * \param codec codec number (1,2,4,8,16,etc.)
+ * \return This returns a static string identifying the format on success, 0 on error.
+ */
+char *ast_codec2str(int codec);
+
+/*! \name AST_Smoother
+*/
+/*@{ */
+/*! \page ast_smooth The AST Frame Smoother
+The ast_smoother interface was designed specifically
+to take frames of variant sizes and produce frames of a single expected
+size, precisely what you want to do.
+
+The basic interface is:
+
+- Initialize with ast_smoother_new()
+- Queue input frames with ast_smoother_feed()
+- Get output frames with ast_smoother_read()
+- when you're done, free the structure with ast_smoother_free()
+- Also see ast_smoother_test_flag(), ast_smoother_set_flags(), ast_smoother_get_flags(), ast_smoother_reset()
+*/
+struct ast_smoother;
+
+struct ast_smoother *ast_smoother_new(int bytes);
+void ast_smoother_set_flags(struct ast_smoother *smoother, int flags);
+int ast_smoother_get_flags(struct ast_smoother *smoother);
+int ast_smoother_test_flag(struct ast_smoother *s, int flag);
+void ast_smoother_free(struct ast_smoother *s);
+void ast_smoother_reset(struct ast_smoother *s, int bytes);
+int __ast_smoother_feed(struct ast_smoother *s, struct ast_frame *f, int swap);
+struct ast_frame *ast_smoother_read(struct ast_smoother *s);
+#define ast_smoother_feed(s,f) __ast_smoother_feed(s, f, 0)
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define ast_smoother_feed_be(s,f) __ast_smoother_feed(s, f, 1)
+#define ast_smoother_feed_le(s,f) __ast_smoother_feed(s, f, 0)
+#else
+#define ast_smoother_feed_be(s,f) __ast_smoother_feed(s, f, 0)
+#define ast_smoother_feed_le(s,f) __ast_smoother_feed(s, f, 1)
+#endif
+/*@} Doxygen marker */
+
+struct ast_format_list *ast_get_format_list_index(int index);
+struct ast_format_list *ast_get_format_list(size_t *size);
+void ast_frame_dump(const char *name, struct ast_frame *f, char *prefix);
+
+/*! \page AudioCodecPref Audio Codec Preferences
+
+ In order to negotiate audio codecs in the order they are configured
+ in \<channel\>.conf for a device, we set up codec preference lists
+ in addition to the codec capabilities setting. The capabilities
+ setting is a bitmask of audio and video codecs with no internal
+ order. This will reflect the offer given to the other side, where
+ the prefered codecs will be added to the top of the list in the
+ order indicated by the "allow" lines in the device configuration.
+
+ Video codecs are not included in the preference lists since they
+ can't be transcoded and we just have to pick whatever is supported
+*/
+
+/*!
+ *\brief Initialize an audio codec preference to "no preference".
+ * \arg \ref AudioCodecPref
+*/
+void ast_codec_pref_init(struct ast_codec_pref *pref);
+
+/*!
+ * \brief Codec located at a particular place in the preference index.
+ * \arg \ref AudioCodecPref
+*/
+int ast_codec_pref_index(struct ast_codec_pref *pref, int index);
+
+/*! \brief Remove audio a codec from a preference list */
+void ast_codec_pref_remove(struct ast_codec_pref *pref, int format);
+
+/*! \brief Append a audio codec to a preference list, removing it first if it was already there
+*/
+int ast_codec_pref_append(struct ast_codec_pref *pref, int format);
+
+/*! \brief Prepend an audio codec to a preference list, removing it first if it was already there
+*/
+void ast_codec_pref_prepend(struct ast_codec_pref *pref, int format, int only_if_existing);
+
+/*! \brief Select the best audio format according to preference list from supplied options.
+ If "find_best" is non-zero then if nothing is found, the "Best" format of
+ the format list is selected, otherwise 0 is returned. */
+int ast_codec_choose(struct ast_codec_pref *pref, int formats, int find_best);
+
+/*! \brief Set packet size for codec
+*/
+int ast_codec_pref_setsize(struct ast_codec_pref *pref, int format, int framems);
+
+/*! \brief Get packet size for codec
+*/
+struct ast_format_list ast_codec_pref_getsize(struct ast_codec_pref *pref, int format);
+
+/*! \brief Parse an "allow" or "deny" line in a channel or device configuration
+ and update the capabilities mask and pref if provided.
+ Video codecs are not added to codec preference lists, since we can not transcode
+ \return Returns number of errors encountered during parsing
+ */
+int ast_parse_allow_disallow(struct ast_codec_pref *pref, int *mask, const char *list, int allowing);
+
+/*! \brief Dump audio codec preference list into a string */
+int ast_codec_pref_string(struct ast_codec_pref *pref, char *buf, size_t size);
+
+/*! \brief Shift an audio codec preference list up or down 65 bytes so that it becomes an ASCII string */
+void ast_codec_pref_convert(struct ast_codec_pref *pref, char *buf, size_t size, int right);
+
+/*! \brief Returns the number of samples contained in the frame */
+int ast_codec_get_samples(struct ast_frame *f);
+
+/*! \brief Returns the number of bytes for the number of samples of the given format */
+int ast_codec_get_len(int format, int samples);
+
+/*! \brief Appends a frame to the end of a list of frames, truncating the maximum length of the list */
+struct ast_frame *ast_frame_enqueue(struct ast_frame *head, struct ast_frame *f, int maxlen, int dupe);
+
+
+/*! \brief Gets duration in ms of interpolation frame for a format */
+static inline int ast_codec_interp_len(int format)
+{
+ return (format == AST_FORMAT_ILBC) ? 30 : 20;
+}
+
+/*!
+ \brief Adjusts the volume of the audio samples contained in a frame.
+ \param f The frame containing the samples (must be AST_FRAME_VOICE and AST_FORMAT_SLINEAR)
+ \param adjustment The number of dB to adjust up or down.
+ \return 0 for success, non-zero for an error
+ */
+int ast_frame_adjust_volume(struct ast_frame *f, int adjustment);
+
+/*!
+ \brief Sums two frames of audio samples.
+ \param f1 The first frame (which will contain the result)
+ \param f2 The second frame
+ \return 0 for success, non-zero for an error
+
+ The frames must be AST_FRAME_VOICE and must contain AST_FORMAT_SLINEAR samples,
+ and must contain the same number of samples.
+ */
+int ast_frame_slinear_sum(struct ast_frame *f1, struct ast_frame *f2);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _ASTERISK_FRAME_H */
diff --git a/trunk/include/asterisk/fskmodem.h b/trunk/include/asterisk/fskmodem.h
new file mode 100644
index 000000000..d50e8abde
--- /dev/null
+++ b/trunk/include/asterisk/fskmodem.h
@@ -0,0 +1,81 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2005, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief FSK Modem Support
+ * \note Includes code and algorithms from the Zapata library.
+ */
+
+#ifndef _ASTERISK_FSKMODEM_H
+#define _ASTERISK_FSKMODEM_H
+
+#define PARITY_NONE 0
+#define PARITY_EVEN 1
+#define PARITY_ODD 2
+
+
+#define NCOLA 0x4000
+
+/* new filter structure */
+struct filter_struct {
+
+ int icoefs[8];
+ int ip;
+ int ixv[8];
+ int iyv[8];
+};
+
+typedef struct {
+ int nbit; /*!< Number of Data Bits (5,7,8) */
+ int parity; /*!< Parity 0=none 1=even 2=odd */
+ int instop; /*!< Number of Stop Bits */
+ int hdlc; /*!< Modo Packet */
+ int xi0;
+ int xi1;
+ int xi2;
+
+ int ispb;
+ int icont;
+ int bw; /*!< Band Selector*/
+ int f_mark_idx; /*!< Mark Frequency Index (f_M-500)/5 */
+ int f_space_idx; /*!< Space Frequency Index (f_S-500)/5 */
+ int state;
+
+ int pllispb; /*!<Pll autosense */
+ int pllids;
+ int pllispb2;
+
+ struct filter_struct mark_filter;
+ struct filter_struct space_filter;
+ struct filter_struct demod_filter;
+
+} fsk_data;
+
+/* \brief Retrieve a serial byte into outbyte.
+ Buffer is a pointer into a series of
+ shorts and len records the number of bytes in the buffer. len will be
+ overwritten with the number of bytes left that were not consumed.
+ \return return value is as follows:
+ \arg 0: Still looking for something...
+ \arg 1: An output byte was received and stored in outbyte
+ \arg -1: An error occured in the transmission
+ This must be called with at least 80 bytes of buffer. */
+int fsk_serial(fsk_data *fskd, short *buffer, int *len, int *outbyte);
+int fskmodem_init(fsk_data *fskd);
+
+#endif /* _ASTERISK_FSKMODEM_H */
diff --git a/trunk/include/asterisk/global_datastores.h b/trunk/include/asterisk/global_datastores.h
new file mode 100644
index 000000000..72edabac5
--- /dev/null
+++ b/trunk/include/asterisk/global_datastores.h
@@ -0,0 +1,36 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2007, Digium, Inc.
+ *
+ * Mark Michelson <mmichelson@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief globally accessible channel datastores
+ * \author Mark Michelson <mmichelson@digium.com>
+ */
+
+#ifndef _ASTERISK_GLOBAL_DATASTORE_H
+#define _ASTERISK_GLOBAL_DATASTORE_H
+
+#include "asterisk/channel.h"
+
+extern const struct ast_datastore_info dialed_interface_info;
+
+struct ast_dialed_interface {
+ AST_LIST_ENTRY(ast_dialed_interface) list;
+ char interface[1];
+};
+
+#endif
diff --git a/trunk/include/asterisk/hashtab.h b/trunk/include/asterisk/hashtab.h
new file mode 100644
index 000000000..ed9a95e84
--- /dev/null
+++ b/trunk/include/asterisk/hashtab.h
@@ -0,0 +1,324 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2006, Digium, Inc.
+ *
+ * Steve Murphy <murf@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+#ifndef _ASTERISK_HASHTAB_H_
+#define _ASTERISK_HASHTAB_H_
+#define __USE_UNIX98 1 /* to get the MUTEX_RECURSIVE stuff */
+
+/*! \file
+ * \brief Generic (perhaps overly so) hashtable implementation
+ * \ref AstHash
+ */
+/*! \page AstHash Hash Table support in Asterisk
+
+A hash table is a structure that allows for an exact-match search
+in O(1) (or close to that) time.
+
+The method: given: a set of {key,val} pairs. (at a minimum).
+ given: a hash function, which, given a key,
+ will return an integer. Ideally, each key in the
+ set will have its own unique associated hash value.
+ This hash number will index into an array. "buckets"
+ are what the elements of this array are called. To
+ handle possible collisions in hash values, buckets can form a list.
+
+The key for a value must be contained in the value, or we won't
+be able to find it in the bucket list.
+
+This implementation is pretty generic, because:
+
+ 1. The value and key are expected to be in a structure
+ (along with other data, perhaps) and it's address is a "void *".
+ 2. The pointer to a compare function must be passed in at the
+ time of creation, and is stored in the hashtable.
+ 3. The pointer to a resize function, which returns 1 if the
+ hash table is to be grown. A default routine is provided
+ if the pointer is NULL, and uses the java hashtable metric
+ of a 75% load factor.
+ 4. The pointer to a "new size" function, which returns a preferable
+ new size for the hash table bucket array. By default, a function
+ is supplied which roughly doubles the size of the array, is provided.
+ This size should ideally be a prime number.
+ 5. The hashing function pointer must also be supplied. This function
+ must be written by the user to access the keys in the objects being
+ stored. Some helper functions that use a simple "mult by prime, add
+ the next char", sort of string hash, or a simple modulus of the hash
+ table size for ints, is provided; the user can use these simple
+ algorithms to generate a hash, or implement any other algorithms they
+ wish.
+ 6. Recently updated the hash routines to use Doubly-linked lists for buckets,
+ and added a doubly-linked list that threads thru every bucket in the table.
+ The list of all buckets is on the HashTab struct. The Traversal was modified
+ to go thru this list instead of searching the bucket array for buckets.
+ This also should make it safe to remove a bucket during the traversal.
+ Removal and destruction routines will work faster.
+*/
+
+struct ast_hashtab_bucket
+{
+ const void *object; /*!< whatever it is we are storing in this table */
+ struct ast_hashtab_bucket *next; /*!< a DLL of buckets in hash collision */
+ struct ast_hashtab_bucket *prev; /*!< a DLL of buckets in hash collision */
+ struct ast_hashtab_bucket *tnext; /*!< a DLL of all the hash buckets for traversal */
+ struct ast_hashtab_bucket *tprev; /*!< a DLL of all the hash buckets for traversal */
+};
+
+struct ast_hashtab
+{
+ struct ast_hashtab_bucket **array;
+ struct ast_hashtab_bucket *tlist; /*!< the head of a DLList of all the hashbuckets in the table (for traversal). */
+
+ int (*compare) (const void *a, const void *b); /*!< a ptr to func that returns int, and take two void* ptrs, compares them,
+ rets -1 if a < b; rets 0 if a==b; rets 1 if a>b */
+ int (*newsize) (struct ast_hashtab *tab); /*!< a ptr to func that returns int, a new size for hash tab, based on curr_size */
+ int (*resize) (struct ast_hashtab *tab); /*!< a function to decide whether this hashtable should be resized now */
+ unsigned int (*hash) (const void *obj); /*!< a hash func ptr for this table. Given a raw ptr to an obj,
+ it calcs a hash.*/
+ int hash_tab_size; /*!< the size of the bucket array */
+ int hash_tab_elements; /*!< the number of objects currently stored in the table */
+ int largest_bucket_size; /*!< a stat on the health of the table */
+ int resize_count; /*!< a count of the number of times this table has been
+ resized */
+ int do_locking; /*!< if 1 use locks to guarantee safety of insertions/deletions */
+ /* this spot reserved for the proper lock storage */
+ ast_rwlock_t lock; /* is this as good as it sounds? */
+};
+
+/*! \brief an iterator for traversing the buckets */
+struct ast_hashtab_iter
+{
+ struct ast_hashtab *tab;
+ struct ast_hashtab_bucket *next;
+};
+
+
+/* some standard, default routines for general use */
+
+/*! \brief For sizing the hash table, tells if num is prime or not */
+int ast_is_prime(int num);
+
+/*!
+ * \brief assumes a and b are char *
+ * \return 0 if they match
+*/
+int ast_hashtab_compare_strings(const void *a, const void *b);
+
+/*!
+ * \brief assumes a & b are strings
+ * \return 0 if they match (strcasecmp)
+*/
+int ast_hashtab_compare_strings_nocase(const void *a, const void *b);
+
+/*!
+ * \brief assumes a & b are int *
+ * \retval 0 if match
+ * \retval 1 a > b
+ * \retval -1 a < b
+*/
+int ast_hashtab_compare_ints(const void *a, const void *b);
+
+/*!
+ * \brief assumes a & b are short *
+ * \retval 0 if match
+ * \retval 1 a > b
+ * \retval -1 a < b
+*/
+int ast_hashtab_compare_shorts(const void *a, const void *b);
+
+/*!
+ * \brief determine if resize should occur
+ * \returns 1 if the table is 75% full or more
+*/
+int ast_hashtab_resize_java(struct ast_hashtab *tab);
+
+/*! \brief no resizing; always return 0 */
+int ast_hashtab_resize_tight(struct ast_hashtab *tab);
+
+/*! \brief no resizing; always return 0 */
+int ast_hashtab_resize_none(struct ast_hashtab *tab);
+
+/*! \brief Create a prime number roughly 2x the current table size */
+int ast_hashtab_newsize_java(struct ast_hashtab *tab);
+
+/* not yet specified, probably will return 1.5x the current table size */
+int ast_hashtab_newsize_tight(struct ast_hashtab *tab);
+
+/*! \brief always return current size -- no resizing */
+int ast_hashtab_newsize_none(struct ast_hashtab *tab);
+
+/*!
+ * \brief Hashes a string to a number
+ * \param obj
+ * \note A modulus is applied so it in the range 0 to mod-1
+*/
+unsigned int ast_hashtab_hash_string(const void *obj);
+
+/*! \brief Upperases each char before using them for a hash */
+unsigned int ast_hashtab_hash_string_nocase(const void *obj);
+
+
+unsigned int ast_hashtab_hash_string_sax(const void *obj); /* from Josh */
+
+
+unsigned int ast_hashtab_hash_int(const int num); /* right now, both these funcs are just result = num%modulus; */
+
+
+unsigned int ast_hashtab_hash_short(const short num);
+
+
+/*!
+ * \brief Create the hashtable list
+ * \param initial_buckets starting number of buckets
+ * \param compare a func ptr to compare two elements in the hash -- cannot be null
+ * \param resize a func ptr to decide if the table needs to be resized, a NULL ptr here will cause a default to be used
+ * \param newsize a func ptr that returns a new size of the array. A NULL will cause a default to be used
+ * \param hash a func ptr to do the hashing
+ * \param do_locking use locks to guarantee safety of iterators/insertion/deletion -- real simpleminded right now
+*/
+struct ast_hashtab * ast_hashtab_create(int initial_buckets,
+ int (*compare)(const void *a, const void *b),
+ int (*resize)(struct ast_hashtab *),
+ int (*newsize)(struct ast_hashtab *tab),
+ unsigned int (*hash)(const void *obj),
+ int do_locking );
+
+/*!
+ * \brief This func will free the hash table and all its memory.
+ * \note It doesn't touch the objects stored in it
+ * \param tab
+ * \param objdestroyfunc
+*/
+void ast_hashtab_destroy( struct ast_hashtab *tab, void (*objdestroyfunc)(void *obj));
+
+
+/*!
+ * \brief Insert without checking
+ * \param tab
+ * \param obj
+ *
+ * Normally, you'd insert "safely" by checking to see if the element is
+ * already there; in this case, you must already have checked. If an element
+ * is already in the hashtable, that matches this one, most likely this one
+ * will be found first.
+ * \note will force a resize if the resize func returns 1
+ * \retval 1 on success
+ * \retval 0 if there's a problem
+*/
+int ast_hashtab_insert_immediate(struct ast_hashtab *tab, const void *obj);
+
+/*!
+ * \brief Insert without checking, hashing or locking
+ * \param tab
+ * \param obj
+ * \param h hashed index value
+ *
+ * \note Will force a resize if the resize func returns 1
+ * \retval 1 on success
+ * \retval 0 if there's a problem
+*/
+int ast_hashtab_insert_immediate_bucket(struct ast_hashtab *tab, const void *obj, unsigned int h);
+
+/*!
+ * \brief Check and insert new object only if it is not there.
+ * \note Will force a resize if the resize func returns 1
+ * \retval 1 on success
+ * \retval 0 if there's a problem, or it's already there.
+*/
+int ast_hashtab_insert_safe(struct ast_hashtab *tab, const void *obj);
+
+/*!
+ * \brief Lookup this object in the hash table.
+ * \param tab
+ * \param obj
+ * \retval a ptr if found
+ * \retval NULL if not found
+*/
+void * ast_hashtab_lookup(struct ast_hashtab *tab, const void *obj);
+
+/*!
+ * \brief Use this if have the hash val for the object
+ * \note This and avoid the recalc of the hash (the modulus (table_size) is not applied)
+*/
+void * ast_hashtab_lookup_with_hash(struct ast_hashtab *tab, const void *obj, unsigned int hashval);
+
+/*!
+ * \brief Similar to ast_hashtab_lookup but sets h to the key hash value if the lookup fails.
+ * \note This has the modulus applied, and will not be useful for long term storage if the table is resizable.
+*/
+void * ast_hashtab_lookup_bucket(struct ast_hashtab *tab, const void *obj, unsigned int *h);
+
+/*! \brief Returns key stats for the table */
+void ast_hashtab_get_stats( struct ast_hashtab *tab, int *biggest_bucket_size, int *resize_count, int *num_objects, int *num_buckets);
+
+/*! \brief Returns the number of elements stored in the hashtab */
+int ast_hashtab_size( struct ast_hashtab *tab);
+
+/*! \brief Returns the size of the bucket array in the hashtab */
+int ast_hashtab_capacity( struct ast_hashtab *tab);
+
+/*! \brief Return a copy of the hash table */
+struct ast_hashtab *ast_hashtab_dup(struct ast_hashtab *tab, void *(*obj_dup_func)(const void *obj));
+
+/*! \brief Gives an iterator to hastable */
+struct ast_hashtab_iter *ast_hashtab_start_traversal(struct ast_hashtab *tab);
+
+/*! \brief end the traversal, free the iterator, unlock if necc. */
+void ast_hashtab_end_traversal(struct ast_hashtab_iter *it);
+
+/*! \brief Gets the next object in the list, advances iter one step returns null on end of traversal */
+void *ast_hashtab_next(struct ast_hashtab_iter *it);
+
+/*! \brief Looks up the object, removes the corresponding bucket */
+void *ast_hashtab_remove_object_via_lookup(struct ast_hashtab *tab, void *obj);
+
+/*! \brief Hash the object and then compare ptrs in bucket list instead of
+ calling the compare routine, will remove the bucket */
+void *ast_hashtab_remove_this_object(struct ast_hashtab *tab, void *obj);
+
+/* ------------------ */
+/* for lock-enabled traversals with ability to remove an object during the traversal*/
+/* ------------------ */
+
+/*! \brief Gives an iterator to hastable */
+struct ast_hashtab_iter *ast_hashtab_start_write_traversal(struct ast_hashtab *tab);
+
+/*! \brief Looks up the object, removes the corresponding bucket */
+void *ast_hashtab_remove_object_via_lookup_nolock(struct ast_hashtab *tab, void *obj);
+
+/*! \brief Hash the object and then compare ptrs in bucket list instead of
+ calling the compare routine, will remove the bucket */
+void *ast_hashtab_remove_this_object_nolock(struct ast_hashtab *tab, void *obj);
+
+/* ------------------ */
+/* ------------------ */
+
+/* user-controlled hashtab locking. Create a hashtab without locking, then call the
+ following locking routines yourself to lock the table between threads. */
+
+/*! \brief Call this after you create the table to init the lock */
+void ast_hashtab_initlock(struct ast_hashtab *tab);
+/*! \brief Request a write-lock on the table. */
+void ast_hashtab_wrlock(struct ast_hashtab *tab);
+/*! \brief Request a read-lock on the table -- don't change anything! */
+void ast_hashtab_rdlock(struct ast_hashtab *tab);
+/*! \brief release a read- or write- lock. */
+void ast_hashtab_unlock(struct ast_hashtab *tab);
+/*! \brief Call this before you destroy the table. */
+void ast_hashtab_destroylock(struct ast_hashtab *tab);
+
+
+#endif
diff --git a/trunk/include/asterisk/http.h b/trunk/include/asterisk/http.h
new file mode 100644
index 000000000..4cda5cacc
--- /dev/null
+++ b/trunk/include/asterisk/http.h
@@ -0,0 +1,93 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2006, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+#ifndef _ASTERISK_HTTP_H
+#define _ASTERISK_HTTP_H
+
+#include "asterisk/config.h"
+#include "asterisk/tcptls.h"
+#include "asterisk/linkedlists.h"
+
+/*!
+ * \file http.h
+ * \brief Support for Private Asterisk HTTP Servers.
+ * \note Note: The Asterisk HTTP servers are extremely simple and minimal and
+ * only support the "GET" method.
+ *
+ * \author Mark Spencer <markster@digium.com>
+ *
+ * \note In order to have TLS/SSL support, we need the openssl libraries.
+ * Still we can decide whether or not to use them by commenting
+ * in or out the DO_SSL macro.
+ * TLS/SSL support is basically implemented by reading from a config file
+ * (currently http.conf) the names of the certificate and cipher to use,
+ * and then run ssl_setup() to create an appropriate SSL_CTX (ssl_ctx)
+ * If we support multiple domains, presumably we need to read multiple
+ * certificates.
+ * When we are requested to open a TLS socket, we run make_file_from_fd()
+ * on the socket, to do the necessary setup. At the moment the context's name
+ * is hardwired in the function, but we can certainly make it into an extra
+ * parameter to the function.
+ * We declare most of ssl support variables unconditionally,
+ * because their number is small and this simplifies the code.
+ *
+ * \note: the ssl-support variables (ssl_ctx, do_ssl, certfile, cipher)
+ * and their setup should be moved to a more central place, e.g. asterisk.conf
+ * and the source files that processes it. Similarly, ssl_setup() should
+ * be run earlier in the startup process so modules have it available.
+ */
+
+
+/*! \brief HTTP Callbacks take the socket
+
+ \note The method and the path as arguments and should
+ return the content, allocated with malloc(). Status should be changed to reflect
+ the status of the request if it isn't 200 and title may be set to a malloc()'d string
+ to an appropriate title for non-200 responses. Content length may also be specified.
+\verbatim
+ The return value may include additional headers at the front and MUST include a blank
+ line with \r\n to provide separation between user headers and content (even if no
+ content is specified)
+\endverbatim
+*/
+typedef struct ast_str *(*ast_http_callback)(struct server_instance *ser, const char *uri, struct ast_variable *params, int *status, char **title, int *contentlength);
+
+/*! \brief Definition of a URI reachable in the embedded HTTP server */
+struct ast_http_uri {
+ AST_LIST_ENTRY(ast_http_uri) entry;
+ const char *description;
+ const char *uri;
+ unsigned int has_subtree:1;
+ /*! This URI mapping serves static content */
+ unsigned int static_content:1;
+ ast_http_callback callback;
+};
+
+/*! \brief Link into the Asterisk HTTP server */
+int ast_http_uri_link(struct ast_http_uri *urihandler);
+
+/*! \brief Return an ast_str malloc()'d string containing an HTTP error message */
+struct ast_str *ast_http_error(int status, const char *title, const char *extra_header, const char *text);
+
+/*! \brief Destroy an HTTP server */
+void ast_http_uri_unlink(struct ast_http_uri *urihandler);
+
+int ast_http_init(void);
+int ast_http_reload(void);
+
+#endif /* _ASTERISK_SRV_H */
diff --git a/trunk/include/asterisk/image.h b/trunk/include/asterisk/image.h
new file mode 100644
index 000000000..cfe511904
--- /dev/null
+++ b/trunk/include/asterisk/image.h
@@ -0,0 +1,90 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2006, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief General Asterisk channel definitions for image handling
+ */
+
+#ifndef _ASTERISK_IMAGE_H
+#define _ASTERISK_IMAGE_H
+
+/*! \brief structure associated with registering an image format */
+struct ast_imager {
+ char *name; /*!< Name */
+ char *desc; /*!< Description */
+ char *exts; /*!< Extension(s) (separated by '|' ) */
+ int format; /*!< Image format */
+ struct ast_frame *(*read_image)(int fd, int len); /*!< Read an image from a file descriptor */
+ int (*identify)(int fd); /*!< Identify if this is that type of file */
+ int (*write_image)(int fd, struct ast_frame *frame); /*!< Returns length written */
+ AST_LIST_ENTRY(ast_imager) list; /*!< For linked list */
+};
+
+/*!
+ * \brief Check for image support on a channel
+ * \param chan channel to check
+ * Checks the channel to see if it supports the transmission of images
+ * \return non-zero if image transmission is supported
+ */
+int ast_supports_images(struct ast_channel *chan);
+
+/*!
+ * \brief Sends an image
+ * \param chan channel to send image on
+ * \param filename filename of image to send (minus extension)
+ * Sends an image on the given channel.
+ * \retval 0 on success
+ * \retval -1 on error
+ */
+int ast_send_image(struct ast_channel *chan, char *filename);
+
+/*!
+ * \brief Make an image
+ * \param filename filename of image to prepare
+ * \param preflang preferred language to get the image...?
+ * \param format the format of the file
+ * Make an image from a filename ??? No estoy positivo
+ * \retval an ast_frame on success
+ * \retval NULL on failure
+ */
+struct ast_frame *ast_read_image(char *filename, const char *preflang, int format);
+
+/*!
+ * \brief Register image format
+ * \param imgdrv Populated ast_imager structure with info to register
+ * Registers an image format
+ * \return 0 regardless
+ */
+int ast_image_register(struct ast_imager *imgdrv);
+
+/*!
+ * \brief Unregister an image format
+ * \param imgdrv pointer to the ast_imager structure you wish to unregister
+ * Unregisters the image format passed in.
+ * Returns nothing
+ */
+void ast_image_unregister(struct ast_imager *imgdrv);
+
+/*!
+ * \brief Initialize image stuff
+ * Initializes all the various image stuff. Basically just registers the cli stuff
+ * \return 0 all the time
+ */
+int ast_image_init(void);
+
+#endif /* _ASTERISK_IMAGE_H */
diff --git a/trunk/include/asterisk/indications.h b/trunk/include/asterisk/indications.h
new file mode 100644
index 000000000..2841a9fdf
--- /dev/null
+++ b/trunk/include/asterisk/indications.h
@@ -0,0 +1,89 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ */
+
+/*! \file
+ * \brief BSD Telephony Of Mexico "Tormenta" Tone Zone Support 2/22/01
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Primary Author: Pauline Middelink <middelink@polyware.nl>
+ *
+ */
+
+#ifndef _ASTERISK_INDICATIONS_H
+#define _ASTERISK_INDICATIONS_H
+
+#include "asterisk/lock.h"
+
+/*! \brief Description is a series of tones of the format:
+ [!]freq1[+freq2][/duration] separated by commas. There
+ are no spaces. The sequence is repeated back to the
+ first tone description not preceeded by !. Duration is
+ specified in milliseconds */
+struct ind_tone_zone_sound {
+ struct ind_tone_zone_sound *next; /*!< next element */
+ const char *name; /*!< Identifing name */
+ const char *data; /*!< Actual zone description */
+};
+
+struct ind_tone_zone {
+ AST_RWLIST_ENTRY(ind_tone_zone) list;
+ char country[5]; /*!< Country code */
+ char alias[5]; /*!< is this an alias? */
+ char description[40]; /*!< Description */
+ int nrringcadence; /*!< # registered ringcadence elements */
+ int *ringcadence; /*!< Ring cadence */
+ struct ind_tone_zone_sound *tones; /*!< The known tones for this zone */
+};
+
+/*! \brief set the default tone country */
+int ast_set_indication_country(const char *country);
+
+/*! \brief locate tone_zone, given the country. if country == NULL, use the default country */
+struct ind_tone_zone *ast_get_indication_zone(const char *country);
+/*! \brief locate a tone_zone_sound, given the tone_zone. if tone_zone == NULL, use the default tone_zone */
+struct ind_tone_zone_sound *ast_get_indication_tone(const struct ind_tone_zone *zone, const char *indication);
+
+/*! \brief add a new country, if country exists, it will be replaced. */
+int ast_register_indication_country(struct ind_tone_zone *country);
+/*! \brief remove an existing country and all its indications, country must exist */
+int ast_unregister_indication_country(const char *country);
+/*! \brief add a new indication to a tone_zone. tone_zone must exist. if the indication already
+ * exists, it will be replaced. */
+int ast_register_indication(struct ind_tone_zone *zone, const char *indication, const char *tonelist);
+/*! \brief remove an existing tone_zone's indication. tone_zone must exist */
+int ast_unregister_indication(struct ind_tone_zone *zone, const char *indication);
+
+/*! \brief Start a tone-list going */
+int ast_playtones_start(struct ast_channel *chan, int vol, const char* tonelist, int interruptible);
+/*! \brief Stop the tones from playing */
+void ast_playtones_stop(struct ast_channel *chan);
+
+/*! \brief support for walking through a list of indications */
+struct ind_tone_zone *ast_walk_indications(const struct ind_tone_zone *cur);
+
+#if 0
+extern struct ind_tone_zone *tone_zones;
+extern ast_mutex_t tzlock;
+#endif
+
+#endif /* _ASTERISK_INDICATIONS_H */
diff --git a/trunk/include/asterisk/inline_api.h b/trunk/include/asterisk/inline_api.h
new file mode 100644
index 000000000..2347d09d7
--- /dev/null
+++ b/trunk/include/asterisk/inline_api.h
@@ -0,0 +1,66 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2005, Digium, Inc.
+ *
+ * Kevin P. Fleming <kpfleming@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+#ifndef __ASTERISK_INLINEAPI_H
+#define __ASTERISK_INLINEAPI_H
+
+/*! \file
+ * \brief Inlinable API function macro
+
+ Small API functions that are candidates for inlining need to be specially
+ declared and defined, to ensure that the 'right thing' always happens.
+ For example:
+ - there must _always_ be a non-inlined version of the function
+ available for modules compiled out of the tree to link to
+ - references to a function that cannot be inlined (for any
+ reason that the compiler deems proper) must devolve into an
+ 'extern' reference, instead of 'static', so that multiple
+ copies of the function body are not built in different modules
+ - when LOW_MEMORY is defined, inlining should be disabled
+ completely, even if the compiler is configured to support it
+
+ The AST_INLINE_API macro allows this to happen automatically, when
+ used to define your function. Proper usage is as follows:
+ - define your function one place, in a header file, using the macro
+ to wrap the function (see strings.h or time.h for examples)
+ - choose a module to 'host' the function body for non-inline
+ usages, and in that module _only_, define AST_API_MODULE before
+ including the header file
+ */
+
+#if !defined(LOW_MEMORY)
+
+#if !defined(AST_API_MODULE)
+#define AST_INLINE_API(hdr, body) hdr; extern inline hdr body
+#else
+#define AST_INLINE_API(hdr, body) hdr; hdr body
+#endif
+
+#else /* defined(LOW_MEMORY) */
+
+#if !defined(AST_API_MODULE)
+#define AST_INLINE_API(hdr, body) hdr;
+#else
+#define AST_INLINE_API(hdr, body) hdr; hdr body
+#endif
+
+#endif
+
+#undef AST_API_MODULE
+
+#endif /* __ASTERISK_INLINEAPI_H */
diff --git a/trunk/include/asterisk/io.h b/trunk/include/asterisk/io.h
new file mode 100644
index 000000000..ee22994a4
--- /dev/null
+++ b/trunk/include/asterisk/io.h
@@ -0,0 +1,150 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2005, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief I/O Management (derived from Cheops-NG)
+ */
+
+#ifndef _ASTERISK_IO_H
+#define _ASTERISK_IO_H
+
+#ifdef HAVE_SYS_POLL_H
+#include <sys/poll.h> /* For POLL* constants */
+#else
+#include "asterisk/poll-compat.h"
+#endif
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/*! Input ready */
+#define AST_IO_IN POLLIN
+/*! Output ready */
+#define AST_IO_OUT POLLOUT
+/*! Priority input ready */
+#define AST_IO_PRI POLLPRI
+
+/* Implicitly polled for */
+/*! Error condition (errno or getsockopt) */
+#define AST_IO_ERR POLLERR
+/*! Hangup */
+#define AST_IO_HUP POLLHUP
+/*! Invalid fd */
+#define AST_IO_NVAL POLLNVAL
+
+/*! \brief
+ * An Asterisk IO callback takes its id, a file descriptor, list of events, and
+ * callback data as arguments and returns 0 if it should not be
+ * run again, or non-zero if it should be run again.
+ */
+
+struct io_context;
+
+/*!
+ * \brief Creates a context
+ * Create a context for I/O operations
+ * Basically mallocs an IO structure and sets up some default values.
+ * \return an allocated io_context structure
+ */
+struct io_context *io_context_create(void);
+
+/*!
+ * \brief Destroys a context
+ * \param ioc structure to destroy
+ * Destroy a context for I/O operations
+ * Frees all memory associated with the given io_context structure along with the structure itself
+ */
+void io_context_destroy(struct io_context *ioc);
+
+typedef int (*ast_io_cb)(int *id, int fd, short events, void *cbdata);
+#define AST_IO_CB(a) ((ast_io_cb)(a))
+
+/*!
+ * \brief Adds an IO context
+ * \param ioc which context to use
+ * \param fd which fd to monitor
+ * \param callback callback function to run
+ * \param events event mask of events to wait for
+ * \param data data to pass to the callback
+ * Watch for any of revents activites on fd, calling callback with data as
+ * callback data.
+ * \retval a pointer to ID of the IO event
+ * \retval NULL on failure
+ */
+int *ast_io_add(struct io_context *ioc, int fd, ast_io_cb callback, short events, void *data);
+
+/*!
+ * \brief Changes an IO handler
+ * \param ioc which context to use
+ * \param id
+ * \param fd the fd you wish it to contain now
+ * \param callback new callback function
+ * \param events event mask to wait for
+ * \param data data to pass to the callback function
+ * Change an I/O handler, updating fd if > -1, callback if non-null,
+ * and revents if >-1, and data if non-null.
+ * \retval a pointer to the ID of the IO event
+ * \retval NULL on failure
+ */
+int *ast_io_change(struct io_context *ioc, int *id, int fd, ast_io_cb callback, short events, void *data);
+
+/*!
+ * \brief Removes an IO context
+ * \param ioc which io_context to remove it from
+ * \param id which ID to remove
+ * Remove an I/O id from consideration
+ * \retval 0 on success
+ * \retval -1 on failure
+ */
+int ast_io_remove(struct io_context *ioc, int *id);
+
+/*!
+ * \brief Waits for IO
+ * \param ioc which context to act upon
+ * \param howlong how many milliseconds to wait
+ * Wait for I/O to happen, returning after
+ * howlong milliseconds, and after processing
+ * any necessary I/O.
+ * \return he number of I/O events which took place.
+ */
+int ast_io_wait(struct io_context *ioc, int howlong);
+
+/*!
+ * \brief Dumps the IO array.
+ * Debugging: Dump everything in the I/O array
+ */
+void ast_io_dump(struct io_context *ioc);
+
+/*! Set fd into non-echoing mode (if fd is a tty) */
+
+int ast_hide_password(int fd);
+
+/*!
+ * \brief Restores TTY mode.
+ * Call with result from previous ast_hide_password
+ */
+int ast_restore_tty(int fd, int oldstatus);
+
+int ast_get_termcols(int fd);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _ASTERISK_IO_H */
diff --git a/trunk/include/asterisk/jabber.h b/trunk/include/asterisk/jabber.h
new file mode 100644
index 000000000..4bb8b9130
--- /dev/null
+++ b/trunk/include/asterisk/jabber.h
@@ -0,0 +1,201 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2005, Digium, Inc.
+ *
+ * Matt O'Gorman <mogorman@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief AJI - The Asterisk Jabber Interface
+ * \arg \ref AJI_intro
+ * \ref res_jabber.c
+ * \author Matt O'Gorman <mogorman@digium.com>
+ * \extref IKSEMEL http://iksemel.jabberstudio.org
+ *
+ * \page AJI_intro AJI - The Asterisk Jabber Interface
+ *
+ * The Asterisk Jabber Interface, AJI, publishes an API for
+ * modules to use jabber communication. res_jabber.c implements
+ * a Jabber client and a component that can connect as a service
+ * to Jabber servers.
+ *
+ * \section External dependencies
+ * AJI use the IKSEMEL library found at http://iksemel.jabberstudio.org/
+ *
+ * \section Files
+ * - res_jabber.c
+ * - jabber.h
+ * - chan_gtalk.c
+ *
+ */
+
+#ifndef _ASTERISK_JABBER_H
+#define _ASTERISK_JABBER_H
+
+#ifdef HAVE_OPENSSL
+
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+#define TRY_SECURE 2
+#define SECURE 4
+/* file is read by blocks with this size */
+#define NET_IO_BUF_SIZE 4096
+/* Return value for timeout connection expiration */
+#define IKS_NET_EXPIRED 12
+
+#endif /* HAVE_OPENSSL */
+
+#include <iksemel.h>
+#include "asterisk/astobj.h"
+#include "asterisk/linkedlists.h"
+
+/*
+ * As per RFC 3920 - section 3.1, the maximum length for a full Jabber ID
+ * is 3071 bytes.
+ * The ABNF syntax for jid :
+ * jid = [node "@" ] domain [ "/" resource ]
+ * Each allowable portion of a JID (node identifier, domain identifier,
+ * and resource identifier) MUST NOT be more than 1023 bytes in length,
+ * resulting in a maximum total size (including the '@' and '/' separators)
+ * of 3071 bytes.
+ */
+#define AJI_MAX_JIDLEN 3071
+#define AJI_MAX_RESJIDLEN 1023
+
+enum aji_state {
+ AJI_DISCONNECTING,
+ AJI_DISCONNECTED,
+ AJI_CONNECTING,
+ AJI_CONNECTED
+};
+
+enum {
+ AJI_AUTOPRUNE = (1 << 0),
+ AJI_AUTOREGISTER = (1 << 1)
+};
+
+enum aji_btype {
+ AJI_USER=0,
+ AJI_TRANS=1,
+ AJI_UTRANS=2
+};
+
+struct aji_version {
+ char version[50];
+ int jingle;
+ struct aji_capabilities *parent;
+ struct aji_version *next;
+};
+
+struct aji_capabilities {
+ char node[200];
+ struct aji_version *versions;
+ struct aji_capabilities *next;
+};
+
+struct aji_resource {
+ int status;
+ char resource[AJI_MAX_RESJIDLEN];
+ char *description;
+ struct aji_version *cap;
+ int priority;
+ struct aji_resource *next;
+};
+
+struct aji_message {
+ char *from;
+ char *message;
+ char id[25];
+ time_t arrived;
+ AST_LIST_ENTRY(aji_message) list;
+};
+
+struct aji_buddy {
+ ASTOBJ_COMPONENTS_FULL(struct aji_buddy, AJI_MAX_JIDLEN, 1);
+ char channel[160];
+ struct aji_resource *resources;
+ enum aji_btype btype;
+ unsigned int flags;
+};
+
+struct aji_buddy_container {
+ ASTOBJ_CONTAINER_COMPONENTS(struct aji_buddy);
+};
+
+struct aji_transport_container {
+ ASTOBJ_CONTAINER_COMPONENTS(struct aji_transport);
+};
+
+struct aji_client {
+ ASTOBJ_COMPONENTS(struct aji_client);
+ char password[160];
+ char user[AJI_MAX_JIDLEN];
+ char serverhost[AJI_MAX_RESJIDLEN];
+ char statusmessage[256];
+ char name_space[256];
+ char sid[10]; /* Session ID */
+ char mid[6]; /* Message ID */
+ iksid *jid;
+ iksparser *p;
+ iksfilter *f;
+ ikstack *stack;
+#ifdef HAVE_OPENSSL
+ SSL_CTX *ssl_context;
+ SSL *ssl_session;
+ SSL_METHOD *ssl_method;
+ unsigned int stream_flags;
+#endif /* HAVE_OPENSSL */
+ enum aji_state state;
+ int port;
+ int debug;
+ int usetls;
+ int forcessl;
+ int usesasl;
+ int keepalive;
+ int allowguest;
+ int timeout;
+ int message_timeout;
+ int authorized;
+ unsigned int flags;
+ int component; /* 0 client, 1 component */
+ struct aji_buddy_container buddies;
+ AST_LIST_HEAD(messages,aji_message) messages;
+ void *jingle;
+ pthread_t thread;
+ int priority;
+ enum ikshowtype status;
+};
+
+struct aji_client_container{
+ ASTOBJ_CONTAINER_COMPONENTS(struct aji_client);
+};
+
+/* !Send XML stanza over the established XMPP connection */
+int ast_aji_send(struct aji_client *client, iks *x);
+/*! Send jabber chat message from connected client to jabber URI */
+int ast_aji_send_chat(struct aji_client *client, const char *address, const char *message);
+/*! Disconnect jabber client */
+int ast_aji_disconnect(struct aji_client *client);
+int ast_aji_check_roster(void);
+void ast_aji_increment_mid(char *mid);
+/*! Open Chat session */
+int ast_aji_create_chat(struct aji_client *client,char *room, char *server, char *topic);
+/*! Invite to opened Chat session */
+int ast_aji_invite_chat(struct aji_client *client, char *user, char *room, char *message);
+/*! Join existing Chat session */
+int ast_aji_join_chat(struct aji_client *client,char *room);
+struct aji_client *ast_aji_get_client(const char *name);
+struct aji_client_container *ast_aji_get_clients(void);
+
+#endif
diff --git a/trunk/include/asterisk/jingle.h b/trunk/include/asterisk/jingle.h
new file mode 100644
index 000000000..bc3b0f217
--- /dev/null
+++ b/trunk/include/asterisk/jingle.h
@@ -0,0 +1,61 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2005, Digium, Inc.
+ *
+ * Matt O'Gorman <mogorman@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief Jingle definitions for chan_jingle
+ *
+ * \ref chan_jingle.c
+ *
+ * \author Matt O'Gorman <mogorman@digium.com>
+ */
+
+
+#ifndef _ASTERISK_JINGLE_H
+#define _ASTERISK_JINGLE_H
+
+#include <iksemel.h>
+#include "asterisk/astobj.h"
+
+
+/* Jingle Constants */
+
+#define JINGLE_NODE "jingle"
+#define GOOGLE_NODE "session"
+
+#define JINGLE_NS "http://www.xmpp.org/extensions/xep-0166.html#ns"
+#define JINGLE_AUDIO_RTP_NS "http://www.xmpp.org/extensions/xep-0167.html#ns"
+#define JINGLE_ICE_UDP_NS "http://www.xmpp.org/extensions/xep-0176.html#ns-udp"
+#define JINGLE_DTMF_NS "http://www.xmpp.org/extensions/xep-0181.html#ns"
+#define JINGLE_DTMF_NS_ERRORS "http://www.xmpp.org/extensions/xep-0181.html#ns-errors"
+#define GOOGLE_NS "http://www.google.com/session"
+
+#define JINGLE_SID "sid"
+#define GOOGLE_SID "id"
+
+#define JINGLE_INITIATE "session-initiate"
+
+#define JINGLE_ACCEPT "session-accept"
+#define GOOGLE_ACCEPT "accept"
+
+#define JINGLE_NEGOTIATE "transport-info"
+#define GOOGLE_NEGOTIATE "candidates"
+
+#define JINGLE_INFO "session-info"
+#define JINGLE_TERMINATE "session-terminate"
+
+#endif
diff --git a/trunk/include/asterisk/libresample.h b/trunk/include/asterisk/libresample.h
new file mode 120000
index 000000000..d71269da1
--- /dev/null
+++ b/trunk/include/asterisk/libresample.h
@@ -0,0 +1 @@
+../../main/libresample/include/libresample.h \ No newline at end of file
diff --git a/trunk/include/asterisk/linkedlists.h b/trunk/include/asterisk/linkedlists.h
new file mode 100644
index 000000000..1f3285dfa
--- /dev/null
+++ b/trunk/include/asterisk/linkedlists.h
@@ -0,0 +1,775 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2006, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ * Kevin P. Fleming <kpfleming@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+#ifndef ASTERISK_LINKEDLISTS_H
+#define ASTERISK_LINKEDLISTS_H
+
+#include "asterisk/lock.h"
+
+/*!
+ \file linkedlists.h
+ \brief A set of macros to manage forward-linked lists.
+*/
+
+/*!
+ \brief Locks a list.
+ \param head This is a pointer to the list head structure
+
+ This macro attempts to place an exclusive lock in the
+ list head structure pointed to by head.
+ \retval 0 on success
+ \retval non-zero on failure
+*/
+#define AST_LIST_LOCK(head) \
+ ast_mutex_lock(&(head)->lock)
+
+/*!
+ \brief Write locks a list.
+ \param head This is a pointer to the list head structure
+
+ This macro attempts to place an exclusive write lock in the
+ list head structure pointed to by head.
+ \retval 0 on success
+ \retval non-zero on failure
+*/
+#define AST_RWLIST_WRLOCK(head) \
+ ast_rwlock_wrlock(&(head)->lock)
+
+/*!
+ \brief Read locks a list.
+ \param head This is a pointer to the list head structure
+
+ This macro attempts to place a read lock in the
+ list head structure pointed to by head.
+ \retval 0 on success
+ \retval non-zero on failure
+*/
+#define AST_RWLIST_RDLOCK(head) \
+ ast_rwlock_rdlock(&(head)->lock)
+
+/*!
+ \brief Locks a list, without blocking if the list is locked.
+ \param head This is a pointer to the list head structure
+
+ This macro attempts to place an exclusive lock in the
+ list head structure pointed to by head.
+ \retval 0 on success
+ \retval non-zero on failure
+*/
+#define AST_LIST_TRYLOCK(head) \
+ ast_mutex_trylock(&(head)->lock)
+
+/*!
+ \brief Write locks a list, without blocking if the list is locked.
+ \param head This is a pointer to the list head structure
+
+ This macro attempts to place an exclusive write lock in the
+ list head structure pointed to by head.
+ \retval 0 on success
+ \retval non-zero on failure
+*/
+#define AST_RWLIST_TRYWRLOCK(head) \
+ ast_rwlock_trywrlock(&(head)->lock)
+
+/*!
+ \brief Read locks a list, without blocking if the list is locked.
+ \param head This is a pointer to the list head structure
+
+ This macro attempts to place a read lock in the
+ list head structure pointed to by head.
+ \retval 0 on success
+ \retval non-zero on failure
+*/
+#define AST_RWLIST_TRYRDLOCK(head) \
+ ast_rwlock_tryrdlock(&(head)->lock)
+
+/*!
+ \brief Attempts to unlock a list.
+ \param head This is a pointer to the list head structure
+
+ This macro attempts to remove an exclusive lock from the
+ list head structure pointed to by head. If the list
+ was not locked by this thread, this macro has no effect.
+*/
+#define AST_LIST_UNLOCK(head) \
+ ast_mutex_unlock(&(head)->lock)
+
+/*!
+ \brief Attempts to unlock a read/write based list.
+ \param head This is a pointer to the list head structure
+
+ This macro attempts to remove a read or write lock from the
+ list head structure pointed to by head. If the list
+ was not locked by this thread, this macro has no effect.
+*/
+#define AST_RWLIST_UNLOCK(head) \
+ ast_rwlock_unlock(&(head)->lock)
+
+/*!
+ \brief Defines a structure to be used to hold a list of specified type.
+ \param name This will be the name of the defined structure.
+ \param type This is the type of each list entry.
+
+ This macro creates a structure definition that can be used
+ to hold a list of the entries of type \a type. It does not actually
+ declare (allocate) a structure; to do that, either follow this
+ macro with the desired name of the instance you wish to declare,
+ or use the specified \a name to declare instances elsewhere.
+
+ Example usage:
+ \code
+ static AST_LIST_HEAD(entry_list, entry) entries;
+ \endcode
+
+ This would define \c struct \c entry_list, and declare an instance of it named
+ \a entries, all intended to hold a list of type \c struct \c entry.
+*/
+#define AST_LIST_HEAD(name, type) \
+struct name { \
+ struct type *first; \
+ struct type *last; \
+ ast_mutex_t lock; \
+}
+
+/*!
+ \brief Defines a structure to be used to hold a read/write list of specified type.
+ \param name This will be the name of the defined structure.
+ \param type This is the type of each list entry.
+
+ This macro creates a structure definition that can be used
+ to hold a list of the entries of type \a type. It does not actually
+ declare (allocate) a structure; to do that, either follow this
+ macro with the desired name of the instance you wish to declare,
+ or use the specified \a name to declare instances elsewhere.
+
+ Example usage:
+ \code
+ static AST_RWLIST_HEAD(entry_list, entry) entries;
+ \endcode
+
+ This would define \c struct \c entry_list, and declare an instance of it named
+ \a entries, all intended to hold a list of type \c struct \c entry.
+*/
+#define AST_RWLIST_HEAD(name, type) \
+struct name { \
+ struct type *first; \
+ struct type *last; \
+ ast_rwlock_t lock; \
+}
+
+/*!
+ \brief Defines a structure to be used to hold a list of specified type (with no lock).
+ \param name This will be the name of the defined structure.
+ \param type This is the type of each list entry.
+
+ This macro creates a structure definition that can be used
+ to hold a list of the entries of type \a type. It does not actually
+ declare (allocate) a structure; to do that, either follow this
+ macro with the desired name of the instance you wish to declare,
+ or use the specified \a name to declare instances elsewhere.
+
+ Example usage:
+ \code
+ static AST_LIST_HEAD_NOLOCK(entry_list, entry) entries;
+ \endcode
+
+ This would define \c struct \c entry_list, and declare an instance of it named
+ \a entries, all intended to hold a list of type \c struct \c entry.
+*/
+#define AST_LIST_HEAD_NOLOCK(name, type) \
+struct name { \
+ struct type *first; \
+ struct type *last; \
+}
+
+/*!
+ \brief Defines initial values for a declaration of AST_LIST_HEAD
+*/
+#define AST_LIST_HEAD_INIT_VALUE { \
+ .first = NULL, \
+ .last = NULL, \
+ .lock = AST_MUTEX_INIT_VALUE, \
+ }
+
+/*!
+ \brief Defines initial values for a declaration of AST_RWLIST_HEAD
+*/
+#define AST_RWLIST_HEAD_INIT_VALUE { \
+ .first = NULL, \
+ .last = NULL, \
+ .lock = AST_RWLOCK_INIT_VALUE, \
+ }
+
+/*!
+ \brief Defines initial values for a declaration of AST_LIST_HEAD_NOLOCK
+*/
+#define AST_LIST_HEAD_NOLOCK_INIT_VALUE { \
+ .first = NULL, \
+ .last = NULL, \
+ }
+
+/*!
+ \brief Defines a structure to be used to hold a list of specified type, statically initialized.
+ \param name This will be the name of the defined structure.
+ \param type This is the type of each list entry.
+
+ This macro creates a structure definition that can be used
+ to hold a list of the entries of type \a type, and allocates an instance
+ of it, initialized to be empty.
+
+ Example usage:
+ \code
+ static AST_LIST_HEAD_STATIC(entry_list, entry);
+ \endcode
+
+ This would define \c struct \c entry_list, intended to hold a list of
+ type \c struct \c entry.
+*/
+#if defined(AST_MUTEX_INIT_W_CONSTRUCTORS)
+#define AST_LIST_HEAD_STATIC(name, type) \
+struct name { \
+ struct type *first; \
+ struct type *last; \
+ ast_mutex_t lock; \
+} name; \
+static void __attribute__ ((constructor)) __init_##name(void) \
+{ \
+ AST_LIST_HEAD_INIT(&name); \
+} \
+static void __attribute__ ((destructor)) __fini_##name(void) \
+{ \
+ AST_LIST_HEAD_DESTROY(&name); \
+} \
+struct __dummy_##name
+#else
+#define AST_LIST_HEAD_STATIC(name, type) \
+struct name { \
+ struct type *first; \
+ struct type *last; \
+ ast_mutex_t lock; \
+} name = AST_LIST_HEAD_INIT_VALUE
+#endif
+
+/*!
+ \brief Defines a structure to be used to hold a read/write list of specified type, statically initialized.
+ \param name This will be the name of the defined structure.
+ \param type This is the type of each list entry.
+
+ This macro creates a structure definition that can be used
+ to hold a list of the entries of type \a type, and allocates an instance
+ of it, initialized to be empty.
+
+ Example usage:
+ \code
+ static AST_RWLIST_HEAD_STATIC(entry_list, entry);
+ \endcode
+
+ This would define \c struct \c entry_list, intended to hold a list of
+ type \c struct \c entry.
+*/
+#ifndef AST_RWLOCK_INIT_VALUE
+#define AST_RWLIST_HEAD_STATIC(name, type) \
+struct name { \
+ struct type *first; \
+ struct type *last; \
+ ast_rwlock_t lock; \
+} name; \
+static void __attribute__ ((constructor)) __init_##name(void) \
+{ \
+ AST_RWLIST_HEAD_INIT(&name); \
+} \
+static void __attribute__ ((destructor)) __fini_##name(void) \
+{ \
+ AST_RWLIST_HEAD_DESTROY(&name); \
+} \
+struct __dummy_##name
+#else
+#define AST_RWLIST_HEAD_STATIC(name, type) \
+struct name { \
+ struct type *first; \
+ struct type *last; \
+ ast_rwlock_t lock; \
+} name = AST_RWLIST_HEAD_INIT_VALUE
+#endif
+
+/*!
+ \brief Defines a structure to be used to hold a list of specified type, statically initialized.
+
+ This is the same as AST_LIST_HEAD_STATIC, except without the lock included.
+*/
+#define AST_LIST_HEAD_NOLOCK_STATIC(name, type) \
+struct name { \
+ struct type *first; \
+ struct type *last; \
+} name = AST_LIST_HEAD_NOLOCK_INIT_VALUE
+
+/*!
+ \brief Initializes a list head structure with a specified first entry.
+ \param head This is a pointer to the list head structure
+ \param entry pointer to the list entry that will become the head of the list
+
+ This macro initializes a list head structure by setting the head
+ entry to the supplied value and recreating the embedded lock.
+*/
+#define AST_LIST_HEAD_SET(head, entry) do { \
+ (head)->first = (entry); \
+ (head)->last = (entry); \
+ ast_mutex_init(&(head)->lock); \
+} while (0)
+
+/*!
+ \brief Initializes an rwlist head structure with a specified first entry.
+ \param head This is a pointer to the list head structure
+ \param entry pointer to the list entry that will become the head of the list
+
+ This macro initializes a list head structure by setting the head
+ entry to the supplied value and recreating the embedded lock.
+*/
+#define AST_RWLIST_HEAD_SET(head, entry) do { \
+ (head)->first = (entry); \
+ (head)->last = (entry); \
+ ast_rwlock_init(&(head)->lock); \
+} while (0)
+
+/*!
+ \brief Initializes a list head structure with a specified first entry.
+ \param head This is a pointer to the list head structure
+ \param entry pointer to the list entry that will become the head of the list
+
+ This macro initializes a list head structure by setting the head
+ entry to the supplied value.
+*/
+#define AST_LIST_HEAD_SET_NOLOCK(head, entry) do { \
+ (head)->first = (entry); \
+ (head)->last = (entry); \
+} while (0)
+
+/*!
+ \brief Declare a forward link structure inside a list entry.
+ \param type This is the type of each list entry.
+
+ This macro declares a structure to be used to link list entries together.
+ It must be used inside the definition of the structure named in
+ \a type, as follows:
+
+ \code
+ struct list_entry {
+ ...
+ AST_LIST_ENTRY(list_entry) list;
+ }
+ \endcode
+
+ The field name \a list here is arbitrary, and can be anything you wish.
+*/
+#define AST_LIST_ENTRY(type) \
+struct { \
+ struct type *next; \
+}
+
+#define AST_RWLIST_ENTRY AST_LIST_ENTRY
+
+/*!
+ \brief Returns the first entry contained in a list.
+ \param head This is a pointer to the list head structure
+ */
+#define AST_LIST_FIRST(head) ((head)->first)
+
+#define AST_RWLIST_FIRST AST_LIST_FIRST
+
+/*!
+ \brief Returns the last entry contained in a list.
+ \param head This is a pointer to the list head structure
+ */
+#define AST_LIST_LAST(head) ((head)->last)
+
+#define AST_RWLIST_LAST AST_LIST_LAST
+
+/*!
+ \brief Returns the next entry in the list after the given entry.
+ \param elm This is a pointer to the current entry.
+ \param field This is the name of the field (declared using AST_LIST_ENTRY())
+ used to link entries of this list together.
+*/
+#define AST_LIST_NEXT(elm, field) ((elm)->field.next)
+
+#define AST_RWLIST_NEXT AST_LIST_NEXT
+
+/*!
+ \brief Checks whether the specified list contains any entries.
+ \param head This is a pointer to the list head structure
+
+ \return non-zero if the list has entries
+ \return zero if not.
+ */
+#define AST_LIST_EMPTY(head) (AST_LIST_FIRST(head) == NULL)
+
+#define AST_RWLIST_EMPTY AST_LIST_EMPTY
+
+/*!
+ \brief Loops over (traverses) the entries in a list.
+ \param head This is a pointer to the list head structure
+ \param var This is the name of the variable that will hold a pointer to the
+ current list entry on each iteration. It must be declared before calling
+ this macro.
+ \param field This is the name of the field (declared using AST_LIST_ENTRY())
+ used to link entries of this list together.
+
+ This macro is use to loop over (traverse) the entries in a list. It uses a
+ \a for loop, and supplies the enclosed code with a pointer to each list
+ entry as it loops. It is typically used as follows:
+ \code
+ static AST_LIST_HEAD(entry_list, list_entry) entries;
+ ...
+ struct list_entry {
+ ...
+ AST_LIST_ENTRY(list_entry) list;
+ }
+ ...
+ struct list_entry *current;
+ ...
+ AST_LIST_TRAVERSE(&entries, current, list) {
+ (do something with current here)
+ }
+ \endcode
+ \warning If you modify the forward-link pointer contained in the \a current entry while
+ inside the loop, the behavior will be unpredictable. At a minimum, the following
+ macros will modify the forward-link pointer, and should not be used inside
+ AST_LIST_TRAVERSE() against the entry pointed to by the \a current pointer without
+ careful consideration of their consequences:
+ \li AST_LIST_NEXT() (when used as an lvalue)
+ \li AST_LIST_INSERT_AFTER()
+ \li AST_LIST_INSERT_HEAD()
+ \li AST_LIST_INSERT_TAIL()
+*/
+#define AST_LIST_TRAVERSE(head,var,field) \
+ for((var) = (head)->first; (var); (var) = (var)->field.next)
+
+#define AST_RWLIST_TRAVERSE AST_LIST_TRAVERSE
+
+/*!
+ \brief Loops safely over (traverses) the entries in a list.
+ \param head This is a pointer to the list head structure
+ \param var This is the name of the variable that will hold a pointer to the
+ current list entry on each iteration. It must be declared before calling
+ this macro.
+ \param field This is the name of the field (declared using AST_LIST_ENTRY())
+ used to link entries of this list together.
+
+ This macro is used to safely loop over (traverse) the entries in a list. It
+ uses a \a for loop, and supplies the enclosed code with a pointer to each list
+ entry as it loops. It is typically used as follows:
+
+ \code
+ static AST_LIST_HEAD(entry_list, list_entry) entries;
+ ...
+ struct list_entry {
+ ...
+ AST_LIST_ENTRY(list_entry) list;
+ }
+ ...
+ struct list_entry *current;
+ ...
+ AST_LIST_TRAVERSE_SAFE_BEGIN(&entries, current, list) {
+ (do something with current here)
+ }
+ AST_LIST_TRAVERSE_SAFE_END;
+ \endcode
+
+ It differs from AST_LIST_TRAVERSE() in that the code inside the loop can modify
+ (or even free, after calling AST_LIST_REMOVE_CURRENT()) the entry pointed to by
+ the \a current pointer without affecting the loop traversal.
+*/
+#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field) { \
+ typeof((head)) __list_head = head; \
+ typeof(__list_head->first) __list_next; \
+ typeof(__list_head->first) __list_prev = NULL; \
+ typeof(__list_head->first) __new_prev = NULL; \
+ for ((var) = __list_head->first, __new_prev = (var), \
+ __list_next = (var) ? (var)->field.next : NULL; \
+ (var); \
+ __list_prev = __new_prev, (var) = __list_next, \
+ __new_prev = (var), \
+ __list_next = (var) ? (var)->field.next : NULL \
+ )
+
+#define AST_RWLIST_TRAVERSE_SAFE_BEGIN AST_LIST_TRAVERSE_SAFE_BEGIN
+
+/*!
+ \brief Removes the \a current entry from a list during a traversal.
+ \param field This is the name of the field (declared using AST_LIST_ENTRY())
+ used to link entries of this list together.
+
+ \note This macro can \b only be used inside an AST_LIST_TRAVERSE_SAFE_BEGIN()
+ block; it is used to unlink the current entry from the list without affecting
+ the list traversal (and without having to re-traverse the list to modify the
+ previous entry, if any).
+ */
+#define AST_LIST_REMOVE_CURRENT(field) do { \
+ __new_prev->field.next = NULL; \
+ __new_prev = __list_prev; \
+ if (__list_prev) \
+ __list_prev->field.next = __list_next; \
+ else \
+ __list_head->first = __list_next; \
+ if (!__list_next) \
+ __list_head->last = __list_prev; \
+ } while (0)
+
+#define AST_RWLIST_REMOVE_CURRENT AST_LIST_REMOVE_CURRENT
+
+#define AST_LIST_MOVE_CURRENT(newhead, field) do { \
+ typeof ((newhead)->first) __list_cur = __new_prev; \
+ AST_LIST_REMOVE_CURRENT(field); \
+ AST_LIST_INSERT_TAIL((newhead), __list_cur, field); \
+ } while (0)
+
+#define AST_RWLIST_MOVE_CURRENT AST_LIST_MOVE_CURRENT
+
+/*!
+ \brief Inserts a list entry before the current entry during a traversal.
+ \param elm This is a pointer to the entry to be inserted.
+ \param field This is the name of the field (declared using AST_LIST_ENTRY())
+ used to link entries of this list together.
+
+ \note This macro can \b only be used inside an AST_LIST_TRAVERSE_SAFE_BEGIN()
+ block.
+ */
+#define AST_LIST_INSERT_BEFORE_CURRENT(elm, field) do { \
+ if (__list_prev) { \
+ (elm)->field.next = __list_prev->field.next; \
+ __list_prev->field.next = elm; \
+ } else { \
+ (elm)->field.next = __list_head->first; \
+ __list_head->first = (elm); \
+ } \
+ __new_prev = (elm); \
+} while (0)
+
+#define AST_RWLIST_INSERT_BEFORE_CURRENT AST_LIST_INSERT_BEFORE_CURRENT
+
+/*!
+ \brief Closes a safe loop traversal block.
+ */
+#define AST_LIST_TRAVERSE_SAFE_END }
+
+#define AST_RWLIST_TRAVERSE_SAFE_END AST_LIST_TRAVERSE_SAFE_END
+
+/*!
+ \brief Initializes a list head structure.
+ \param head This is a pointer to the list head structure
+
+ This macro initializes a list head structure by setting the head
+ entry to \a NULL (empty list) and recreating the embedded lock.
+*/
+#define AST_LIST_HEAD_INIT(head) { \
+ (head)->first = NULL; \
+ (head)->last = NULL; \
+ ast_mutex_init(&(head)->lock); \
+}
+
+/*!
+ \brief Initializes an rwlist head structure.
+ \param head This is a pointer to the list head structure
+
+ This macro initializes a list head structure by setting the head
+ entry to \a NULL (empty list) and recreating the embedded lock.
+*/
+#define AST_RWLIST_HEAD_INIT(head) { \
+ (head)->first = NULL; \
+ (head)->last = NULL; \
+ ast_rwlock_init(&(head)->lock); \
+}
+
+/*!
+ \brief Destroys a list head structure.
+ \param head This is a pointer to the list head structure
+
+ This macro destroys a list head structure by setting the head
+ entry to \a NULL (empty list) and destroying the embedded lock.
+ It does not free the structure from memory.
+*/
+#define AST_LIST_HEAD_DESTROY(head) { \
+ (head)->first = NULL; \
+ (head)->last = NULL; \
+ ast_mutex_destroy(&(head)->lock); \
+}
+
+/*!
+ \brief Destroys an rwlist head structure.
+ \param head This is a pointer to the list head structure
+
+ This macro destroys a list head structure by setting the head
+ entry to \a NULL (empty list) and destroying the embedded lock.
+ It does not free the structure from memory.
+*/
+#define AST_RWLIST_HEAD_DESTROY(head) { \
+ (head)->first = NULL; \
+ (head)->last = NULL; \
+ ast_rwlock_destroy(&(head)->lock); \
+}
+
+/*!
+ \brief Initializes a list head structure.
+ \param head This is a pointer to the list head structure
+
+ This macro initializes a list head structure by setting the head
+ entry to \a NULL (empty list). There is no embedded lock handling
+ with this macro.
+*/
+#define AST_LIST_HEAD_INIT_NOLOCK(head) { \
+ (head)->first = NULL; \
+ (head)->last = NULL; \
+}
+
+/*!
+ \brief Inserts a list entry after a given entry.
+ \param head This is a pointer to the list head structure
+ \param listelm This is a pointer to the entry after which the new entry should
+ be inserted.
+ \param elm This is a pointer to the entry to be inserted.
+ \param field This is the name of the field (declared using AST_LIST_ENTRY())
+ used to link entries of this list together.
+ */
+#define AST_LIST_INSERT_AFTER(head, listelm, elm, field) do { \
+ (elm)->field.next = (listelm)->field.next; \
+ (listelm)->field.next = (elm); \
+ if ((head)->last == (listelm)) \
+ (head)->last = (elm); \
+} while (0)
+
+#define AST_RWLIST_INSERT_AFTER AST_LIST_INSERT_AFTER
+
+/*!
+ \brief Inserts a list entry at the head of a list.
+ \param head This is a pointer to the list head structure
+ \param elm This is a pointer to the entry to be inserted.
+ \param field This is the name of the field (declared using AST_LIST_ENTRY())
+ used to link entries of this list together.
+ */
+#define AST_LIST_INSERT_HEAD(head, elm, field) do { \
+ (elm)->field.next = (head)->first; \
+ (head)->first = (elm); \
+ if (!(head)->last) \
+ (head)->last = (elm); \
+} while (0)
+
+#define AST_RWLIST_INSERT_HEAD AST_LIST_INSERT_HEAD
+
+/*!
+ \brief Appends a list entry to the tail of a list.
+ \param head This is a pointer to the list head structure
+ \param elm This is a pointer to the entry to be appended.
+ \param field This is the name of the field (declared using AST_LIST_ENTRY())
+ used to link entries of this list together.
+
+ Note: The link field in the appended entry is \b not modified, so if it is
+ actually the head of a list itself, the entire list will be appended
+ temporarily (until the next AST_LIST_INSERT_TAIL is performed).
+ */
+#define AST_LIST_INSERT_TAIL(head, elm, field) do { \
+ if (!(head)->first) { \
+ (head)->first = (elm); \
+ (head)->last = (elm); \
+ } else { \
+ (head)->last->field.next = (elm); \
+ (head)->last = (elm); \
+ } \
+} while (0)
+
+#define AST_RWLIST_INSERT_TAIL AST_LIST_INSERT_TAIL
+
+/*!
+ \brief Appends a whole list to the tail of a list.
+ \param head This is a pointer to the list head structure
+ \param list This is a pointer to the list to be appended.
+ \param field This is the name of the field (declared using AST_LIST_ENTRY())
+ used to link entries of this list together.
+
+ Note: The source list (the \a list parameter) will be empty after
+ calling this macro (the list entries are \b moved to the target list).
+ */
+#define AST_LIST_APPEND_LIST(head, list, field) do { \
+ if (!(head)->first) { \
+ (head)->first = (list)->first; \
+ (head)->last = (list)->last; \
+ } else { \
+ (head)->last->field.next = (list)->first; \
+ (head)->last = (list)->last; \
+ } \
+ (list)->first = NULL; \
+ (list)->last = NULL; \
+} while (0)
+
+#define AST_RWLIST_APPEND_LIST AST_LIST_APPEND_LIST
+
+/*!
+ \brief Removes and returns the head entry from a list.
+ \param head This is a pointer to the list head structure
+ \param field This is the name of the field (declared using AST_LIST_ENTRY())
+ used to link entries of this list together.
+
+ Removes the head entry from the list, and returns a pointer to it.
+ This macro is safe to call on an empty list.
+ */
+#define AST_LIST_REMOVE_HEAD(head, field) ({ \
+ typeof((head)->first) cur = (head)->first; \
+ if (cur) { \
+ (head)->first = cur->field.next; \
+ cur->field.next = NULL; \
+ if ((head)->last == cur) \
+ (head)->last = NULL; \
+ } \
+ cur; \
+ })
+
+#define AST_RWLIST_REMOVE_HEAD AST_LIST_REMOVE_HEAD
+
+/*!
+ \brief Removes a specific entry from a list.
+ \param head This is a pointer to the list head structure
+ \param elm This is a pointer to the entry to be removed.
+ \param field This is the name of the field (declared using AST_LIST_ENTRY())
+ used to link entries of this list together.
+ \warning The removed entry is \b not freed nor modified in any way.
+ */
+#define AST_LIST_REMOVE(head, elm, field) ({ \
+ __typeof(elm) __res = NULL; \
+ if ((head)->first == (elm)) { \
+ __res = (head)->first; \
+ (head)->first = (elm)->field.next; \
+ if ((head)->last == (elm)) \
+ (head)->last = NULL; \
+ } else { \
+ typeof(elm) curelm = (head)->first; \
+ while (curelm && (curelm->field.next != (elm))) \
+ curelm = curelm->field.next; \
+ if (curelm) { \
+ __res = (elm); \
+ curelm->field.next = (elm)->field.next; \
+ if ((head)->last == (elm)) \
+ (head)->last = curelm; \
+ } \
+ } \
+ (elm)->field.next = NULL; \
+ (__res); \
+})
+
+#define AST_RWLIST_REMOVE AST_LIST_REMOVE
+
+#endif /* _ASTERISK_LINKEDLISTS_H */
diff --git a/trunk/include/asterisk/localtime.h b/trunk/include/asterisk/localtime.h
new file mode 100644
index 000000000..dd92871e9
--- /dev/null
+++ b/trunk/include/asterisk/localtime.h
@@ -0,0 +1,48 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2005, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ * Tilghman Lesher <tlesher@vcch.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief Custom localtime functions for multiple timezones
+ */
+
+#ifndef _ASTERISK_LOCALTIME_H
+#define _ASTERISK_LOCALTIME_H
+
+struct ast_tm {
+ int tm_sec; /*!< Seconds. [0-60] (1 leap second) */
+ int tm_min; /*!< Minutes. [0-59] */
+ int tm_hour; /*!< Hours. [0-23] */
+ int tm_mday; /*!< Day. [1-31] */
+ int tm_mon; /*!< Month. [0-11] */
+ int tm_year; /*!< Year - 1900. */
+ int tm_wday; /*!< Day of week. [0-6] */
+ int tm_yday; /*!< Days in year.[0-365] */
+ int tm_isdst; /*!< DST. [-1/0/1]*/
+ long int tm_gmtoff; /*!< Seconds east of UTC. */
+ char *tm_zone; /*!< Timezone abbreviation. */
+ /* NOTE: do NOT reorder this final item. The order needs to remain compatible with struct tm */
+ int tm_usec; /*!< microseconds */
+};
+
+struct ast_tm *ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone);
+void ast_get_dst_info(const time_t * const timep, int *dst_enabled, time_t *dst_start, time_t *dst_end, int *gmt_off, const char * const zone);
+struct timeval ast_mktime(struct ast_tm * const tmp, const char *zone);
+int ast_strftime(char *buf, size_t len, const char *format, const struct ast_tm *tm);
+
+#endif /* _ASTERISK_LOCALTIME_H */
diff --git a/trunk/include/asterisk/lock.h b/trunk/include/asterisk/lock.h
new file mode 100644
index 000000000..f9a6a5831
--- /dev/null
+++ b/trunk/include/asterisk/lock.h
@@ -0,0 +1,1205 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2006, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief Asterisk locking-related definitions:
+ * - ast_mutext_t, ast_rwlock_t and related functions;
+ * - atomic arithmetic instructions;
+ * - wrappers for channel locking.
+ *
+ * - See \ref LockDef
+ */
+
+/*! \page LockDef Asterisk thread locking models
+ *
+ * This file provides different implementation of the functions,
+ * depending on the platform, the use of DEBUG_THREADS, and the way
+ * module-level mutexes are initialized.
+ *
+ * - \b static: the mutex is assigned the value AST_MUTEX_INIT_VALUE
+ * this is done at compile time, and is the way used on Linux.
+ * This method is not applicable to all platforms e.g. when the
+ * initialization needs that some code is run.
+ *
+ * - \b through constructors: for each mutex, a constructor function is
+ * defined, which then runs when the program (or the module)
+ * starts. The problem with this approach is that there is a
+ * lot of code duplication (a new block of code is created for
+ * each mutex). Also, it does not prevent a user from declaring
+ * a global mutex without going through the wrapper macros,
+ * so sane programming practices are still required.
+ */
+
+#ifndef _ASTERISK_LOCK_H
+#define _ASTERISK_LOCK_H
+
+#include <pthread.h>
+#include <sys/param.h>
+
+#include "asterisk/logger.h"
+
+/* internal macro to profile mutexes. Only computes the delay on
+ * non-blocking calls.
+ */
+#ifndef HAVE_MTX_PROFILE
+#define __MTX_PROF(a) return pthread_mutex_lock((a))
+#else
+#define __MTX_PROF(a) do { \
+ int i; \
+ /* profile only non-blocking events */ \
+ ast_mark(mtx_prof, 1); \
+ i = pthread_mutex_trylock((a)); \
+ ast_mark(mtx_prof, 0); \
+ if (!i) \
+ return i; \
+ else \
+ return pthread_mutex_lock((a)); \
+ } while (0)
+#endif /* HAVE_MTX_PROFILE */
+
+#define AST_PTHREADT_NULL (pthread_t) -1
+#define AST_PTHREADT_STOP (pthread_t) -2
+
+#if defined(SOLARIS) || defined(BSD)
+#define AST_MUTEX_INIT_W_CONSTRUCTORS
+#endif /* SOLARIS || BSD */
+
+/* Asterisk REQUIRES recursive (not error checking) mutexes
+ and will not run without them. */
+#if defined(HAVE_PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP) && defined(HAVE_PTHREAD_MUTEX_RECURSIVE_NP)
+#define PTHREAD_MUTEX_INIT_VALUE PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
+#define AST_MUTEX_KIND PTHREAD_MUTEX_RECURSIVE_NP
+#else
+#define PTHREAD_MUTEX_INIT_VALUE PTHREAD_MUTEX_INITIALIZER
+#define AST_MUTEX_KIND PTHREAD_MUTEX_RECURSIVE
+#endif /* PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP */
+
+/*
+ * Definition of ast_mutex_t, ast_cont_d and related functions with/without debugging
+ * (search for DEBUG_THREADS to find the start/end of the sections).
+ *
+ * The non-debug code contains just wrappers for the corresponding pthread functions.
+ * The debug code tracks usage and tries to identify deadlock situations.
+ */
+#ifdef DEBUG_THREADS
+
+#define __ast_mutex_logger(...) do { if (canlog) ast_log(LOG_ERROR, __VA_ARGS__); else fprintf(stderr, __VA_ARGS__); } while (0)
+
+#ifdef THREAD_CRASH
+#define DO_THREAD_CRASH do { *((int *)(0)) = 1; } while(0)
+#else
+#define DO_THREAD_CRASH do { } while (0)
+#endif
+
+#include <errno.h>
+
+#define AST_MUTEX_INIT_VALUE { PTHREAD_MUTEX_INIT_VALUE, 1, { NULL }, { 0 }, 0, { NULL }, { 0 }, PTHREAD_MUTEX_INIT_VALUE }
+#define AST_MUTEX_INIT_VALUE_NOTRACKING \
+ { PTHREAD_MUTEX_INIT_VALUE, 0, { NULL }, { 0 }, 0, { NULL }, { 0 }, PTHREAD_MUTEX_INIT_VALUE }
+
+#define AST_MAX_REENTRANCY 10
+
+struct ast_channel;
+
+struct ast_mutex_info {
+ pthread_mutex_t mutex;
+ /*! Track which thread holds this lock */
+ unsigned int track:1;
+ const char *file[AST_MAX_REENTRANCY];
+ int lineno[AST_MAX_REENTRANCY];
+ int reentrancy;
+ const char *func[AST_MAX_REENTRANCY];
+ pthread_t thread[AST_MAX_REENTRANCY];
+ pthread_mutex_t reentr_mutex;
+};
+
+typedef struct ast_mutex_info ast_mutex_t;
+
+typedef pthread_cond_t ast_cond_t;
+
+static pthread_mutex_t empty_mutex;
+
+enum ast_lock_type {
+ AST_MUTEX,
+ AST_RDLOCK,
+ AST_WRLOCK,
+};
+
+/*!
+ * \brief Store lock info for the current thread
+ *
+ * This function gets called in ast_mutex_lock() and ast_mutex_trylock() so
+ * that information about this lock can be stored in this thread's
+ * lock info struct. The lock is marked as pending as the thread is waiting
+ * on the lock. ast_mark_lock_acquired() will mark it as held by this thread.
+ */
+void ast_store_lock_info(enum ast_lock_type type, const char *filename,
+ int line_num, const char *func, const char *lock_name, void *lock_addr);
+
+/*!
+ * \brief Mark the last lock as acquired
+ */
+void ast_mark_lock_acquired(void);
+
+/*!
+ * \brief Mark the last lock as failed (trylock)
+ */
+void ast_mark_lock_failed(void);
+
+/*!
+ * \brief remove lock info for the current thread
+ *
+ * this gets called by ast_mutex_unlock so that information on the lock can
+ * be removed from the current thread's lock info struct.
+ */
+void ast_remove_lock_info(void *lock_addr);
+
+static void __attribute__((constructor)) init_empty_mutex(void)
+{
+ memset(&empty_mutex, 0, sizeof(empty_mutex));
+}
+
+static inline void ast_reentrancy_lock(ast_mutex_t *p_ast_mutex)
+{
+ pthread_mutex_lock(&p_ast_mutex->reentr_mutex);
+}
+
+static inline void ast_reentrancy_unlock(ast_mutex_t *p_ast_mutex)
+{
+ pthread_mutex_unlock(&p_ast_mutex->reentr_mutex);
+}
+
+static inline void ast_reentrancy_init(ast_mutex_t *p_ast_mutex)
+{
+ int i;
+ pthread_mutexattr_t reentr_attr;
+
+ for (i = 0; i < AST_MAX_REENTRANCY; i++) {
+ p_ast_mutex->file[i] = NULL;
+ p_ast_mutex->lineno[i] = 0;
+ p_ast_mutex->func[i] = NULL;
+ p_ast_mutex->thread[i] = 0;
+ }
+
+ p_ast_mutex->reentrancy = 0;
+
+ pthread_mutexattr_init(&reentr_attr);
+ pthread_mutexattr_settype(&reentr_attr, AST_MUTEX_KIND);
+ pthread_mutex_init(&p_ast_mutex->reentr_mutex, &reentr_attr);
+ pthread_mutexattr_destroy(&reentr_attr);
+}
+
+static inline void delete_reentrancy_cs(ast_mutex_t * p_ast_mutex)
+{
+ pthread_mutex_destroy(&p_ast_mutex->reentr_mutex);
+}
+
+static inline int __ast_pthread_mutex_init(int track, const char *filename, int lineno, const char *func,
+ const char *mutex_name, ast_mutex_t *t)
+{
+ int res;
+ pthread_mutexattr_t attr;
+
+#ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
+
+ if ((t->mutex) != ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
+/*
+ int canlog = strcmp(filename, "logger.c") & track;
+ __ast_mutex_logger("%s line %d (%s): NOTICE: mutex '%s' is already initialized.\n",
+ filename, lineno, func, mutex_name);
+ DO_THREAD_CRASH;
+*/
+ return 0;
+ }
+
+#endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
+
+ ast_reentrancy_init(t);
+ t->track = track;
+
+ pthread_mutexattr_init(&attr);
+ pthread_mutexattr_settype(&attr, AST_MUTEX_KIND);
+
+ res = pthread_mutex_init(&t->mutex, &attr);
+ pthread_mutexattr_destroy(&attr);
+ return res;
+}
+
+#define ast_mutex_init(pmutex) __ast_pthread_mutex_init(1, __FILE__, __LINE__, __PRETTY_FUNCTION__, #pmutex, pmutex)
+#define ast_mutex_init_notracking(pmutex) \
+ __ast_pthread_mutex_init(0, __FILE__, __LINE__, __PRETTY_FUNCTION__, #pmutex, pmutex)
+
+static inline int __ast_pthread_mutex_destroy(const char *filename, int lineno, const char *func,
+ const char *mutex_name, ast_mutex_t *t)
+{
+ int res;
+ int canlog = strcmp(filename, "logger.c") & t->track;
+
+#ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
+ if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
+ /* Don't try to uninitialize non initialized mutex
+ * This may no effect on linux
+ * And always ganerate core on *BSD with
+ * linked libpthread
+ * This not error condition if the mutex created on the fly.
+ */
+ __ast_mutex_logger("%s line %d (%s): NOTICE: mutex '%s' is uninitialized.\n",
+ filename, lineno, func, mutex_name);
+ return 0;
+ }
+#endif
+
+ res = pthread_mutex_trylock(&t->mutex);
+ switch (res) {
+ case 0:
+ pthread_mutex_unlock(&t->mutex);
+ break;
+ case EINVAL:
+ __ast_mutex_logger("%s line %d (%s): Error: attempt to destroy invalid mutex '%s'.\n",
+ filename, lineno, func, mutex_name);
+ break;
+ case EBUSY:
+ __ast_mutex_logger("%s line %d (%s): Error: attempt to destroy locked mutex '%s'.\n",
+ filename, lineno, func, mutex_name);
+ ast_reentrancy_lock(t);
+ __ast_mutex_logger("%s line %d (%s): Error: '%s' was locked here.\n",
+ t->file[t->reentrancy-1], t->lineno[t->reentrancy-1], t->func[t->reentrancy-1], mutex_name);
+ ast_reentrancy_unlock(t);
+ break;
+ }
+
+ if ((res = pthread_mutex_destroy(&t->mutex)))
+ __ast_mutex_logger("%s line %d (%s): Error destroying mutex %s: %s\n",
+ filename, lineno, func, mutex_name, strerror(res));
+#ifndef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
+ else
+ t->mutex = PTHREAD_MUTEX_INIT_VALUE;
+#endif
+ ast_reentrancy_lock(t);
+ t->file[0] = filename;
+ t->lineno[0] = lineno;
+ t->func[0] = func;
+ t->reentrancy = 0;
+ t->thread[0] = 0;
+ ast_reentrancy_unlock(t);
+ delete_reentrancy_cs(t);
+
+ return res;
+}
+
+static inline int __ast_pthread_mutex_lock(const char *filename, int lineno, const char *func,
+ const char* mutex_name, ast_mutex_t *t)
+{
+ int res;
+ int canlog = strcmp(filename, "logger.c") & t->track;
+
+#if defined(AST_MUTEX_INIT_W_CONSTRUCTORS)
+ if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
+ /* Don't warn abount uninitialized mutex.
+ * Simple try to initialize it.
+ * May be not needed in linux system.
+ */
+ res = __ast_pthread_mutex_init(t->track, filename, lineno, func, mutex_name, t);
+ if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
+ __ast_mutex_logger("%s line %d (%s): Error: mutex '%s' is uninitialized and unable to initialize.\n",
+ filename, lineno, func, mutex_name);
+ return res;
+ }
+ }
+#endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
+
+ if (t->track)
+ ast_store_lock_info(AST_MUTEX, filename, lineno, func, mutex_name, &t->mutex);
+
+#ifdef DETECT_DEADLOCKS
+ {
+ time_t seconds = time(NULL);
+ time_t wait_time, reported_wait = 0;
+ do {
+#ifdef HAVE_MTX_PROFILE
+ ast_mark(mtx_prof, 1);
+#endif
+ res = pthread_mutex_trylock(&t->mutex);
+#ifdef HAVE_MTX_PROFILE
+ ast_mark(mtx_prof, 0);
+#endif
+ if (res == EBUSY) {
+ wait_time = time(NULL) - seconds;
+ if (wait_time > reported_wait && (wait_time % 5) == 0) {
+ __ast_mutex_logger("%s line %d (%s): Deadlock? waited %d sec for mutex '%s'?\n",
+ filename, lineno, func, (int) wait_time, mutex_name);
+ ast_reentrancy_lock(t);
+ __ast_mutex_logger("%s line %d (%s): '%s' was locked here.\n",
+ t->file[t->reentrancy-1], t->lineno[t->reentrancy-1],
+ t->func[t->reentrancy-1], mutex_name);
+ ast_reentrancy_unlock(t);
+ reported_wait = wait_time;
+ }
+ usleep(200);
+ }
+ } while (res == EBUSY);
+ }
+#else
+#ifdef HAVE_MTX_PROFILE
+ ast_mark(mtx_prof, 1);
+ res = pthread_mutex_trylock(&t->mutex);
+ ast_mark(mtx_prof, 0);
+ if (res)
+#endif
+ res = pthread_mutex_lock(&t->mutex);
+#endif /* DETECT_DEADLOCKS */
+
+ if (!res) {
+ ast_reentrancy_lock(t);
+ if (t->reentrancy < AST_MAX_REENTRANCY) {
+ t->file[t->reentrancy] = filename;
+ t->lineno[t->reentrancy] = lineno;
+ t->func[t->reentrancy] = func;
+ t->thread[t->reentrancy] = pthread_self();
+ t->reentrancy++;
+ } else {
+ __ast_mutex_logger("%s line %d (%s): '%s' really deep reentrancy!\n",
+ filename, lineno, func, mutex_name);
+ }
+ ast_reentrancy_unlock(t);
+ if (t->track)
+ ast_mark_lock_acquired();
+ } else {
+ if (t->track)
+ ast_remove_lock_info(&t->mutex);
+ __ast_mutex_logger("%s line %d (%s): Error obtaining mutex: %s\n",
+ filename, lineno, func, strerror(res));
+ DO_THREAD_CRASH;
+ }
+
+ return res;
+}
+
+static inline int __ast_pthread_mutex_trylock(const char *filename, int lineno, const char *func,
+ const char* mutex_name, ast_mutex_t *t)
+{
+ int res;
+ int canlog = strcmp(filename, "logger.c") & t->track;
+
+#if defined(AST_MUTEX_INIT_W_CONSTRUCTORS)
+ if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
+ /* Don't warn abount uninitialized mutex.
+ * Simple try to initialize it.
+ * May be not needed in linux system.
+ */
+ res = __ast_pthread_mutex_init(t->track, filename, lineno, func, mutex_name, t);
+ if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
+ __ast_mutex_logger("%s line %d (%s): Error: mutex '%s' is uninitialized and unable to initialize.\n",
+ filename, lineno, func, mutex_name);
+ return res;
+ }
+ }
+#endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
+
+ if (t->track)
+ ast_store_lock_info(AST_MUTEX, filename, lineno, func, mutex_name, &t->mutex);
+
+ if (!(res = pthread_mutex_trylock(&t->mutex))) {
+ ast_reentrancy_lock(t);
+ if (t->reentrancy < AST_MAX_REENTRANCY) {
+ t->file[t->reentrancy] = filename;
+ t->lineno[t->reentrancy] = lineno;
+ t->func[t->reentrancy] = func;
+ t->thread[t->reentrancy] = pthread_self();
+ t->reentrancy++;
+ } else {
+ __ast_mutex_logger("%s line %d (%s): '%s' really deep reentrancy!\n",
+ filename, lineno, func, mutex_name);
+ }
+ ast_reentrancy_unlock(t);
+ if (t->track)
+ ast_mark_lock_acquired();
+ } else if (t->track) {
+ ast_mark_lock_failed();
+ }
+
+ return res;
+}
+
+static inline int __ast_pthread_mutex_unlock(const char *filename, int lineno, const char *func,
+ const char *mutex_name, ast_mutex_t *t)
+{
+ int res;
+ int canlog = strcmp(filename, "logger.c") & t->track;
+
+#ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
+ if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
+ __ast_mutex_logger("%s line %d (%s): Error: mutex '%s' is uninitialized.\n",
+ filename, lineno, func, mutex_name);
+ res = __ast_pthread_mutex_init(t->track, filename, lineno, func, mutex_name, t);
+ if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
+ __ast_mutex_logger("%s line %d (%s): Error: mutex '%s' is uninitialized and unable to initialize.\n",
+ filename, lineno, func, mutex_name);
+ }
+ return res;
+ }
+#endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
+
+ ast_reentrancy_lock(t);
+ if (t->reentrancy && (t->thread[t->reentrancy-1] != pthread_self())) {
+ __ast_mutex_logger("%s line %d (%s): attempted unlock mutex '%s' without owning it!\n",
+ filename, lineno, func, mutex_name);
+ __ast_mutex_logger("%s line %d (%s): '%s' was locked here.\n",
+ t->file[t->reentrancy-1], t->lineno[t->reentrancy-1], t->func[t->reentrancy-1], mutex_name);
+ DO_THREAD_CRASH;
+ }
+
+ if (--t->reentrancy < 0) {
+ __ast_mutex_logger("%s line %d (%s): mutex '%s' freed more times than we've locked!\n",
+ filename, lineno, func, mutex_name);
+ t->reentrancy = 0;
+ }
+
+ if (t->reentrancy < AST_MAX_REENTRANCY) {
+ t->file[t->reentrancy] = NULL;
+ t->lineno[t->reentrancy] = 0;
+ t->func[t->reentrancy] = NULL;
+ t->thread[t->reentrancy] = 0;
+ }
+ ast_reentrancy_unlock(t);
+
+ if (t->track)
+ ast_remove_lock_info(&t->mutex);
+
+ if ((res = pthread_mutex_unlock(&t->mutex))) {
+ __ast_mutex_logger("%s line %d (%s): Error releasing mutex: %s\n",
+ filename, lineno, func, strerror(res));
+ DO_THREAD_CRASH;
+ }
+
+ return res;
+}
+
+static inline int __ast_cond_init(const char *filename, int lineno, const char *func,
+ const char *cond_name, ast_cond_t *cond, pthread_condattr_t *cond_attr)
+{
+ return pthread_cond_init(cond, cond_attr);
+}
+
+static inline int __ast_cond_signal(const char *filename, int lineno, const char *func,
+ const char *cond_name, ast_cond_t *cond)
+{
+ return pthread_cond_signal(cond);
+}
+
+static inline int __ast_cond_broadcast(const char *filename, int lineno, const char *func,
+ const char *cond_name, ast_cond_t *cond)
+{
+ return pthread_cond_broadcast(cond);
+}
+
+static inline int __ast_cond_destroy(const char *filename, int lineno, const char *func,
+ const char *cond_name, ast_cond_t *cond)
+{
+ return pthread_cond_destroy(cond);
+}
+
+static inline int __ast_cond_wait(const char *filename, int lineno, const char *func,
+ const char *cond_name, const char *mutex_name,
+ ast_cond_t *cond, ast_mutex_t *t)
+{
+ int res;
+ int canlog = strcmp(filename, "logger.c") & t->track;
+
+#ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
+ if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
+ __ast_mutex_logger("%s line %d (%s): Error: mutex '%s' is uninitialized.\n",
+ filename, lineno, func, mutex_name);
+ res = __ast_pthread_mutex_init(t->track, filename, lineno, func, mutex_name, t);
+ if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
+ __ast_mutex_logger("%s line %d (%s): Error: mutex '%s' is uninitialized and unable to initialize.\n",
+ filename, lineno, func, mutex_name);
+ }
+ return res;
+ }
+#endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
+
+ ast_reentrancy_lock(t);
+ if (t->reentrancy && (t->thread[t->reentrancy-1] != pthread_self())) {
+ __ast_mutex_logger("%s line %d (%s): attempted unlock mutex '%s' without owning it!\n",
+ filename, lineno, func, mutex_name);
+ __ast_mutex_logger("%s line %d (%s): '%s' was locked here.\n",
+ t->file[t->reentrancy-1], t->lineno[t->reentrancy-1], t->func[t->reentrancy-1], mutex_name);
+ DO_THREAD_CRASH;
+ }
+
+ if (--t->reentrancy < 0) {
+ __ast_mutex_logger("%s line %d (%s): mutex '%s' freed more times than we've locked!\n",
+ filename, lineno, func, mutex_name);
+ t->reentrancy = 0;
+ }
+
+ if (t->reentrancy < AST_MAX_REENTRANCY) {
+ t->file[t->reentrancy] = NULL;
+ t->lineno[t->reentrancy] = 0;
+ t->func[t->reentrancy] = NULL;
+ t->thread[t->reentrancy] = 0;
+ }
+ ast_reentrancy_unlock(t);
+
+ if (t->track)
+ ast_remove_lock_info(&t->mutex);
+
+ if ((res = pthread_cond_wait(cond, &t->mutex))) {
+ __ast_mutex_logger("%s line %d (%s): Error waiting on condition mutex '%s'\n",
+ filename, lineno, func, strerror(res));
+ DO_THREAD_CRASH;
+ } else {
+ ast_reentrancy_lock(t);
+ if (t->reentrancy < AST_MAX_REENTRANCY) {
+ t->file[t->reentrancy] = filename;
+ t->lineno[t->reentrancy] = lineno;
+ t->func[t->reentrancy] = func;
+ t->thread[t->reentrancy] = pthread_self();
+ t->reentrancy++;
+ } else {
+ __ast_mutex_logger("%s line %d (%s): '%s' really deep reentrancy!\n",
+ filename, lineno, func, mutex_name);
+ }
+ ast_reentrancy_unlock(t);
+
+ if (t->track)
+ ast_store_lock_info(AST_MUTEX, filename, lineno, func, mutex_name, &t->mutex);
+ }
+
+ return res;
+}
+
+static inline int __ast_cond_timedwait(const char *filename, int lineno, const char *func,
+ const char *cond_name, const char *mutex_name, ast_cond_t *cond,
+ ast_mutex_t *t, const struct timespec *abstime)
+{
+ int res;
+ int canlog = strcmp(filename, "logger.c") & t->track;
+
+#ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
+ if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
+ __ast_mutex_logger("%s line %d (%s): Error: mutex '%s' is uninitialized.\n",
+ filename, lineno, func, mutex_name);
+ res = __ast_pthread_mutex_init(t->track, filename, lineno, func, mutex_name, t);
+ if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
+ __ast_mutex_logger("%s line %d (%s): Error: mutex '%s' is uninitialized and unable to initialize.\n",
+ filename, lineno, func, mutex_name);
+ }
+ return res;
+ }
+#endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
+
+ ast_reentrancy_lock(t);
+ if (t->reentrancy && (t->thread[t->reentrancy-1] != pthread_self())) {
+ __ast_mutex_logger("%s line %d (%s): attempted unlock mutex '%s' without owning it!\n",
+ filename, lineno, func, mutex_name);
+ __ast_mutex_logger("%s line %d (%s): '%s' was locked here.\n",
+ t->file[t->reentrancy-1], t->lineno[t->reentrancy-1], t->func[t->reentrancy-1], mutex_name);
+ DO_THREAD_CRASH;
+ }
+
+ if (--t->reentrancy < 0) {
+ __ast_mutex_logger("%s line %d (%s): mutex '%s' freed more times than we've locked!\n",
+ filename, lineno, func, mutex_name);
+ t->reentrancy = 0;
+ }
+
+ if (t->reentrancy < AST_MAX_REENTRANCY) {
+ t->file[t->reentrancy] = NULL;
+ t->lineno[t->reentrancy] = 0;
+ t->func[t->reentrancy] = NULL;
+ t->thread[t->reentrancy] = 0;
+ }
+ ast_reentrancy_unlock(t);
+
+ if (t->track)
+ ast_remove_lock_info(&t->mutex);
+
+ if ((res = pthread_cond_timedwait(cond, &t->mutex, abstime)) && (res != ETIMEDOUT)) {
+ __ast_mutex_logger("%s line %d (%s): Error waiting on condition mutex '%s'\n",
+ filename, lineno, func, strerror(res));
+ DO_THREAD_CRASH;
+ } else {
+ ast_reentrancy_lock(t);
+ if (t->reentrancy < AST_MAX_REENTRANCY) {
+ t->file[t->reentrancy] = filename;
+ t->lineno[t->reentrancy] = lineno;
+ t->func[t->reentrancy] = func;
+ t->thread[t->reentrancy] = pthread_self();
+ t->reentrancy++;
+ } else {
+ __ast_mutex_logger("%s line %d (%s): '%s' really deep reentrancy!\n",
+ filename, lineno, func, mutex_name);
+ }
+ ast_reentrancy_unlock(t);
+
+ if (t->track)
+ ast_store_lock_info(AST_MUTEX, filename, lineno, func, mutex_name, &t->mutex);
+ }
+
+ return res;
+}
+
+#define ast_mutex_destroy(a) __ast_pthread_mutex_destroy(__FILE__, __LINE__, __PRETTY_FUNCTION__, #a, a)
+#define ast_mutex_lock(a) __ast_pthread_mutex_lock(__FILE__, __LINE__, __PRETTY_FUNCTION__, #a, a)
+#define ast_mutex_unlock(a) __ast_pthread_mutex_unlock(__FILE__, __LINE__, __PRETTY_FUNCTION__, #a, a)
+#define ast_mutex_trylock(a) __ast_pthread_mutex_trylock(__FILE__, __LINE__, __PRETTY_FUNCTION__, #a, a)
+#define ast_cond_init(cond, attr) __ast_cond_init(__FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, cond, attr)
+#define ast_cond_destroy(cond) __ast_cond_destroy(__FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, cond)
+#define ast_cond_signal(cond) __ast_cond_signal(__FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, cond)
+#define ast_cond_broadcast(cond) __ast_cond_broadcast(__FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, cond)
+#define ast_cond_wait(cond, mutex) __ast_cond_wait(__FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, #mutex, cond, mutex)
+#define ast_cond_timedwait(cond, mutex, time) __ast_cond_timedwait(__FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, #mutex, cond, mutex, time)
+
+#else /* !DEBUG_THREADS */
+
+
+typedef pthread_mutex_t ast_mutex_t;
+
+#define AST_MUTEX_INIT_VALUE ((ast_mutex_t) PTHREAD_MUTEX_INIT_VALUE)
+#define AST_MUTEX_INIT_VALUE_NOTRACKING ((ast_mutex_t) PTHREAD_MUTEX_INIT_VALUE)
+
+#define ast_mutex_init_notracking(m) ast_mutex_init(m)
+
+static inline int ast_mutex_init(ast_mutex_t *pmutex)
+{
+ int res;
+ pthread_mutexattr_t attr;
+
+ pthread_mutexattr_init(&attr);
+ pthread_mutexattr_settype(&attr, AST_MUTEX_KIND);
+
+ res = pthread_mutex_init(pmutex, &attr);
+ pthread_mutexattr_destroy(&attr);
+ return res;
+}
+
+#define ast_pthread_mutex_init(pmutex,a) pthread_mutex_init(pmutex,a)
+
+static inline int ast_mutex_unlock(ast_mutex_t *pmutex)
+{
+ return pthread_mutex_unlock(pmutex);
+}
+
+static inline int ast_mutex_destroy(ast_mutex_t *pmutex)
+{
+ return pthread_mutex_destroy(pmutex);
+}
+
+static inline int ast_mutex_lock(ast_mutex_t *pmutex)
+{
+ __MTX_PROF(pmutex);
+}
+
+static inline int ast_mutex_trylock(ast_mutex_t *pmutex)
+{
+ return pthread_mutex_trylock(pmutex);
+}
+
+typedef pthread_cond_t ast_cond_t;
+
+static inline int ast_cond_init(ast_cond_t *cond, pthread_condattr_t *cond_attr)
+{
+ return pthread_cond_init(cond, cond_attr);
+}
+
+static inline int ast_cond_signal(ast_cond_t *cond)
+{
+ return pthread_cond_signal(cond);
+}
+
+static inline int ast_cond_broadcast(ast_cond_t *cond)
+{
+ return pthread_cond_broadcast(cond);
+}
+
+static inline int ast_cond_destroy(ast_cond_t *cond)
+{
+ return pthread_cond_destroy(cond);
+}
+
+static inline int ast_cond_wait(ast_cond_t *cond, ast_mutex_t *t)
+{
+ return pthread_cond_wait(cond, t);
+}
+
+static inline int ast_cond_timedwait(ast_cond_t *cond, ast_mutex_t *t, const struct timespec *abstime)
+{
+ return pthread_cond_timedwait(cond, t, abstime);
+}
+
+#endif /* !DEBUG_THREADS */
+
+#if defined(AST_MUTEX_INIT_W_CONSTRUCTORS)
+/*
+ * If AST_MUTEX_INIT_W_CONSTRUCTORS is defined, use file scope constructors
+ * and destructors to create/destroy global mutexes.
+ */
+#define __AST_MUTEX_DEFINE(scope, mutex, init_val, track) \
+ scope ast_mutex_t mutex = init_val; \
+static void __attribute__ ((constructor)) init_##mutex(void) \
+{ \
+ if (track) \
+ ast_mutex_init(&mutex); \
+ else \
+ ast_mutex_init_notracking(&mutex); \
+} \
+ \
+static void __attribute__ ((destructor)) fini_##mutex(void) \
+{ \
+ ast_mutex_destroy(&mutex); \
+}
+#else /* !AST_MUTEX_INIT_W_CONSTRUCTORS */
+/* By default, use static initialization of mutexes. */
+#define __AST_MUTEX_DEFINE(scope, mutex, init_val, track) scope ast_mutex_t mutex = init_val
+#endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
+
+#ifndef __CYGWIN__ /* temporary disabled for cygwin */
+#define pthread_mutex_t use_ast_mutex_t_instead_of_pthread_mutex_t
+#define pthread_cond_t use_ast_cond_t_instead_of_pthread_cond_t
+#endif
+#define pthread_mutex_lock use_ast_mutex_lock_instead_of_pthread_mutex_lock
+#define pthread_mutex_unlock use_ast_mutex_unlock_instead_of_pthread_mutex_unlock
+#define pthread_mutex_trylock use_ast_mutex_trylock_instead_of_pthread_mutex_trylock
+#define pthread_mutex_init use_ast_mutex_init_instead_of_pthread_mutex_init
+#define pthread_mutex_destroy use_ast_mutex_destroy_instead_of_pthread_mutex_destroy
+#define pthread_cond_init use_ast_cond_init_instead_of_pthread_cond_init
+#define pthread_cond_destroy use_ast_cond_destroy_instead_of_pthread_cond_destroy
+#define pthread_cond_signal use_ast_cond_signal_instead_of_pthread_cond_signal
+#define pthread_cond_broadcast use_ast_cond_broadcast_instead_of_pthread_cond_broadcast
+#define pthread_cond_wait use_ast_cond_wait_instead_of_pthread_cond_wait
+#define pthread_cond_timedwait use_ast_cond_timedwait_instead_of_pthread_cond_timedwait
+
+#define AST_MUTEX_DEFINE_STATIC(mutex) __AST_MUTEX_DEFINE(static, mutex, AST_MUTEX_INIT_VALUE, 1)
+#define AST_MUTEX_DEFINE_STATIC_NOTRACKING(mutex) __AST_MUTEX_DEFINE(static, mutex, AST_MUTEX_INIT_VALUE_NOTRACKING, 0)
+
+#define AST_MUTEX_INITIALIZER __use_AST_MUTEX_DEFINE_STATIC_rather_than_AST_MUTEX_INITIALIZER__
+
+#define gethostbyname __gethostbyname__is__not__reentrant__use__ast_gethostbyname__instead__
+
+#ifndef __linux__
+#define pthread_create __use_ast_pthread_create_instead__
+#endif
+
+/*
+ * Same as above, definitions of ast_rwlock_t for the various cases:
+ * simple wrappers for the pthread equivalent in the non-debug case,
+ * more sophisticated tracking in the debug case.
+ */
+
+typedef pthread_rwlock_t ast_rwlock_t;
+
+#ifdef HAVE_PTHREAD_RWLOCK_INITIALIZER
+#define AST_RWLOCK_INIT_VALUE PTHREAD_RWLOCK_INITIALIZER
+#else
+#define AST_RWLOCK_INIT_VALUE { 0 }
+#endif
+
+#ifdef DEBUG_THREADS
+
+#define ast_rwlock_init(rwlock) __ast_rwlock_init(__FILE__, __LINE__, __PRETTY_FUNCTION__, #rwlock, rwlock)
+#define ast_rwlock_destroy(rwlock) __ast_rwlock_destroy(__FILE__, __LINE__, __PRETTY_FUNCTION__, #rwlock, rwlock)
+#define ast_rwlock_unlock(a) _ast_rwlock_unlock(a, # a, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+#define ast_rwlock_rdlock(a) _ast_rwlock_rdlock(a, # a, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+#define ast_rwlock_wrlock(a) _ast_rwlock_wrlock(a, # a, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+#define ast_rwlock_tryrdlock(a) _ast_rwlock_tryrdlock(a, # a, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+#define ast_rwlock_trywrlock(a) _ast_rwlock_trywrlock(a, # a, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+
+
+static inline int __ast_rwlock_init(const char *filename, int lineno, const char *func, const char *rwlock_name, ast_rwlock_t *prwlock)
+{
+ int res;
+ pthread_rwlockattr_t attr;
+#ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
+ int canlog = strcmp(filename, "logger.c");
+
+ if (*prwlock != ((ast_rwlock_t) AST_RWLOCK_INIT_VALUE)) {
+ __ast_mutex_logger("%s line %d (%s): Warning: rwlock '%s' is already initialized.\n",
+ filename, lineno, func, rwlock_name);
+ return 0;
+ }
+#endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
+ pthread_rwlockattr_init(&attr);
+
+#ifdef HAVE_PTHREAD_RWLOCK_PREFER_WRITER_NP
+ pthread_rwlockattr_setkind_np(&attr, PTHREAD_RWLOCK_PREFER_WRITER_NP);
+#endif
+
+ res = pthread_rwlock_init(prwlock, &attr);
+ pthread_rwlockattr_destroy(&attr);
+ return res;
+}
+
+
+static inline int __ast_rwlock_destroy(const char *filename, int lineno, const char *func, const char *rwlock_name, ast_rwlock_t *prwlock)
+{
+ int res;
+ int canlog = strcmp(filename, "logger.c");
+
+#ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
+ if (*prwlock == ((ast_rwlock_t) AST_RWLOCK_INIT_VALUE)) {
+ __ast_mutex_logger("%s line %d (%s): Warning: rwlock '%s' is uninitialized.\n",
+ filename, lineno, func, rwlock_name);
+ return 0;
+ }
+#endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
+
+ if ((res = pthread_rwlock_destroy(prwlock)))
+ __ast_mutex_logger("%s line %d (%s): Error destroying rwlock %s: %s\n",
+ filename, lineno, func, rwlock_name, strerror(res));
+
+ return res;
+}
+
+
+static inline int _ast_rwlock_unlock(ast_rwlock_t *lock, const char *name,
+ const char *file, int line, const char *func)
+{
+ int res;
+#ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
+ int canlog = strcmp(file, "logger.c");
+
+ if (*lock == ((ast_rwlock_t) AST_RWLOCK_INIT_VALUE)) {
+ __ast_mutex_logger("%s line %d (%s): Warning: rwlock '%s' is uninitialized.\n",
+ file, line, func, name);
+ res = __ast_rwlock_init(file, line, func, name, lock);
+ if (*lock == ((ast_rwlock_t) AST_RWLOCK_INIT_VALUE)) {
+ __ast_mutex_logger("%s line %d (%s): Error: rwlock '%s' is uninitialized and unable to initialize.\n",
+ file, line, func, name);
+ }
+ return res;
+ }
+#endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
+
+ res = pthread_rwlock_unlock(lock);
+ ast_remove_lock_info(lock);
+ return res;
+}
+
+
+static inline int _ast_rwlock_rdlock(ast_rwlock_t *lock, const char *name,
+ const char *file, int line, const char *func)
+{
+ int res;
+#ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
+ int canlog = strcmp(file, "logger.c");
+
+ if (*lock == ((ast_rwlock_t) AST_RWLOCK_INIT_VALUE)) {
+ /* Don't warn abount uninitialized lock.
+ * Simple try to initialize it.
+ * May be not needed in linux system.
+ */
+ res = __ast_rwlock_init(file, line, func, name, lock);
+ if (*lock == ((ast_rwlock_t) AST_RWLOCK_INIT_VALUE)) {
+ __ast_mutex_logger("%s line %d (%s): Error: rwlock '%s' is uninitialized and unable to initialize.\n",
+ file, line, func, name);
+ return res;
+ }
+ }
+#endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
+
+ ast_store_lock_info(AST_RDLOCK, file, line, func, name, lock);
+ res = pthread_rwlock_rdlock(lock);
+ if (!res)
+ ast_mark_lock_acquired();
+ else
+ ast_remove_lock_info(lock);
+ return res;
+}
+
+
+static inline int _ast_rwlock_wrlock(ast_rwlock_t *lock, const char *name,
+ const char *file, int line, const char *func)
+{
+ int res;
+#ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
+ int canlog = strcmp(file, "logger.c");
+
+ if (*lock == ((ast_rwlock_t) AST_RWLOCK_INIT_VALUE)) {
+ /* Don't warn abount uninitialized lock.
+ * Simple try to initialize it.
+ * May be not needed in linux system.
+ */
+ res = __ast_rwlock_init(file, line, func, name, lock);
+ if (*lock == ((ast_rwlock_t) AST_RWLOCK_INIT_VALUE)) {
+ __ast_mutex_logger("%s line %d (%s): Error: rwlock '%s' is uninitialized and unable to initialize.\n",
+ file, line, func, name);
+ return res;
+ }
+ }
+#endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
+
+ ast_store_lock_info(AST_WRLOCK, file, line, func, name, lock);
+ res = pthread_rwlock_wrlock(lock);
+ if (!res)
+ ast_mark_lock_acquired();
+ else
+ ast_remove_lock_info(lock);
+ return res;
+}
+
+
+static inline int _ast_rwlock_tryrdlock(ast_rwlock_t *lock, const char *name,
+ const char *file, int line, const char *func)
+{
+ int res;
+#ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
+ int canlog = strcmp(file, "logger.c");
+
+ if (*lock == ((ast_rwlock_t) AST_RWLOCK_INIT_VALUE)) {
+ /* Don't warn abount uninitialized lock.
+ * Simple try to initialize it.
+ * May be not needed in linux system.
+ */
+ res = __ast_rwlock_init(file, line, func, name, lock);
+ if (*lock == ((ast_rwlock_t) AST_RWLOCK_INIT_VALUE)) {
+ __ast_mutex_logger("%s line %d (%s): Error: rwlock '%s' is uninitialized and unable to initialize.\n",
+ file, line, func, name);
+ return res;
+ }
+ }
+#endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
+
+ ast_store_lock_info(AST_RDLOCK, file, line, func, name, lock);
+ res = pthread_rwlock_tryrdlock(lock);
+ if (!res)
+ ast_mark_lock_acquired();
+ else
+ ast_remove_lock_info(lock);
+ return res;
+}
+
+
+static inline int _ast_rwlock_trywrlock(ast_rwlock_t *lock, const char *name,
+ const char *file, int line, const char *func)
+{
+ int res;
+#ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
+ int canlog = strcmp(file, "logger.c");
+
+ if (*lock == ((ast_rwlock_t) AST_RWLOCK_INIT_VALUE)) {
+ /* Don't warn abount uninitialized lock.
+ * Simple try to initialize it.
+ * May be not needed in linux system.
+ */
+ res = __ast_rwlock_init(file, line, func, name, lock);
+ if (*lock == ((ast_rwlock_t) AST_RWLOCK_INIT_VALUE)) {
+ __ast_mutex_logger("%s line %d (%s): Error: rwlock '%s' is uninitialized and unable to initialize.\n",
+ file, line, func, name);
+ return res;
+ }
+ }
+#endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
+
+ ast_store_lock_info(AST_WRLOCK, file, line, func, name, lock);
+ res = pthread_rwlock_trywrlock(lock);
+ if (!res)
+ ast_mark_lock_acquired();
+ else
+ ast_remove_lock_info(lock);
+ return res;
+}
+
+#else /* !DEBUG_THREADS */
+
+static inline int ast_rwlock_init(ast_rwlock_t *prwlock)
+{
+ int res;
+ pthread_rwlockattr_t attr;
+
+ pthread_rwlockattr_init(&attr);
+
+#ifdef HAVE_PTHREAD_RWLOCK_PREFER_WRITER_NP
+ pthread_rwlockattr_setkind_np(&attr, PTHREAD_RWLOCK_PREFER_WRITER_NP);
+#endif
+
+ res = pthread_rwlock_init(prwlock, &attr);
+ pthread_rwlockattr_destroy(&attr);
+ return res;
+}
+
+static inline int ast_rwlock_destroy(ast_rwlock_t *prwlock)
+{
+ return pthread_rwlock_destroy(prwlock);
+}
+
+static inline int ast_rwlock_unlock(ast_rwlock_t *prwlock)
+{
+ return pthread_rwlock_unlock(prwlock);
+}
+
+static inline int ast_rwlock_rdlock(ast_rwlock_t *prwlock)
+{
+ return pthread_rwlock_rdlock(prwlock);
+}
+
+static inline int ast_rwlock_tryrdlock(ast_rwlock_t *prwlock)
+{
+ return pthread_rwlock_tryrdlock(prwlock);
+}
+
+static inline int ast_rwlock_wrlock(ast_rwlock_t *prwlock)
+{
+ return pthread_rwlock_wrlock(prwlock);
+}
+
+static inline int ast_rwlock_trywrlock(ast_rwlock_t *prwlock)
+{
+ return pthread_rwlock_trywrlock(prwlock);
+}
+#endif /* !DEBUG_THREADS */
+
+/* Statically declared read/write locks */
+
+#ifndef HAVE_PTHREAD_RWLOCK_INITIALIZER
+#define __AST_RWLOCK_DEFINE(scope, rwlock) \
+ scope ast_rwlock_t rwlock; \
+static void __attribute__ ((constructor)) init_##rwlock(void) \
+{ \
+ ast_rwlock_init(&rwlock); \
+} \
+ \
+static void __attribute__ ((destructor)) fini_##rwlock(void) \
+{ \
+ ast_rwlock_destroy(&rwlock); \
+}
+#else
+#define __AST_RWLOCK_DEFINE(scope, rwlock) scope ast_rwlock_t rwlock = AST_RWLOCK_INIT_VALUE
+#endif
+
+#define AST_RWLOCK_DEFINE_STATIC(rwlock) __AST_RWLOCK_DEFINE(static, rwlock)
+
+/*
+ * Support for atomic instructions.
+ * For platforms that have it, use the native cpu instruction to
+ * implement them. For other platforms, resort to a 'slow' version
+ * (defined in utils.c) that protects the atomic instruction with
+ * a single lock.
+ * The slow versions is always available, for testing purposes,
+ * as ast_atomic_fetchadd_int_slow()
+ */
+
+int ast_atomic_fetchadd_int_slow(volatile int *p, int v);
+
+#include "asterisk/inline_api.h"
+
+#if defined(HAVE_OSX_ATOMICS)
+#include "libkern/OSAtomic.h"
+#endif
+
+/*! \brief Atomically add v to *p and return * the previous value of *p.
+ * This can be used to handle reference counts, and the return value
+ * can be used to generate unique identifiers.
+ */
+
+#if defined(HAVE_GCC_ATOMICS)
+AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
+{
+ return __sync_fetch_and_add(p, v);
+})
+#elif defined(HAVE_OSX_ATOMICS) && (SIZEOF_INT == 4)
+AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
+{
+ return OSAtomicAdd32(v, (int32_t *) p) - v;
+})
+#elif defined(HAVE_OSX_ATOMICS) && (SIZEOF_INT == 8)
+AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
+{
+ return OSAtomicAdd64(v, (int64_t *) p) - v;
+#elif defined (__i386__) || defined(__x86_64__)
+#ifdef sun
+AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
+{
+ __asm __volatile (
+ " lock; xaddl %0, %1 ; "
+ : "+r" (v), /* 0 (result) */
+ "=m" (*p) /* 1 */
+ : "m" (*p)); /* 2 */
+ return (v);
+})
+#else /* ifndef sun */
+AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
+{
+ __asm __volatile (
+ " lock xaddl %0, %1 ; "
+ : "+r" (v), /* 0 (result) */
+ "=m" (*p) /* 1 */
+ : "m" (*p)); /* 2 */
+ return (v);
+})
+#endif
+#else /* low performance version in utils.c */
+AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
+{
+ return ast_atomic_fetchadd_int_slow(p, v);
+})
+#endif
+
+/*! \brief decrement *p by 1 and return true if the variable has reached 0.
+ * Useful e.g. to check if a refcount has reached 0.
+ */
+#if defined(HAVE_GCC_ATOMICS)
+AST_INLINE_API(int ast_atomic_dec_and_test(volatile int *p),
+{
+ return __sync_sub_and_fetch(p, 1) == 0;
+})
+#elif defined(HAVE_OSX_ATOMICS) && (SIZEOF_INT == 4)
+AST_INLINE_API(int ast_atomic_dec_and_test(volatile int *p),
+{
+ return OSAtomicAdd32( -1, (int32_t *) p) == 0;
+})
+#elif defined(HAVE_OSX_ATOMICS) && (SIZEOF_INT == 8)
+AST_INLINE_API(int ast_atomic_dec_and_test(volatile int *p),
+{
+ return OSAtomicAdd64( -1, (int64_t *) p) == 0;
+#else
+AST_INLINE_API(int ast_atomic_dec_and_test(volatile int *p),
+{
+ int a = ast_atomic_fetchadd_int(p, -1);
+ return a == 1; /* true if the value is 0 now (so it was 1 previously) */
+})
+#endif
+
+#ifndef DEBUG_CHANNEL_LOCKS
+/*! \brief Lock a channel. If DEBUG_CHANNEL_LOCKS is defined
+ in the Makefile, print relevant output for debugging */
+#define ast_channel_lock(x) ast_mutex_lock(&x->lock_dont_use)
+/*! \brief Unlock a channel. If DEBUG_CHANNEL_LOCKS is defined
+ in the Makefile, print relevant output for debugging */
+#define ast_channel_unlock(x) ast_mutex_unlock(&x->lock_dont_use)
+/*! \brief Try locking a channel. If DEBUG_CHANNEL_LOCKS is defined
+ in the Makefile, print relevant output for debugging */
+#define ast_channel_trylock(x) ast_mutex_trylock(&x->lock_dont_use)
+#else
+
+/*! \brief Lock AST channel (and print debugging output)
+\note You need to enable DEBUG_CHANNEL_LOCKS for this function */
+int ast_channel_lock(struct ast_channel *chan);
+
+/*! \brief Unlock AST channel (and print debugging output)
+\note You need to enable DEBUG_CHANNEL_LOCKS for this function
+*/
+int ast_channel_unlock(struct ast_channel *chan);
+
+/*! \brief Lock AST channel (and print debugging output)
+\note You need to enable DEBUG_CHANNEL_LOCKS for this function */
+int ast_channel_trylock(struct ast_channel *chan);
+#endif
+
+#endif /* _ASTERISK_LOCK_H */
diff --git a/trunk/include/asterisk/logger.h b/trunk/include/asterisk/logger.h
new file mode 100644
index 000000000..d76aa932f
--- /dev/null
+++ b/trunk/include/asterisk/logger.h
@@ -0,0 +1,178 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2005, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*!
+ \file logger.h
+ \brief Support for logging to various files, console and syslog
+ Configuration in file logger.conf
+*/
+
+#ifndef _ASTERISK_LOGGER_H
+#define _ASTERISK_LOGGER_H
+
+#include "asterisk/options.h" /* need option_debug */
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+#define EVENTLOG "event_log"
+#define QUEUELOG "queue_log"
+
+#define DEBUG_M(a) { \
+ a; \
+}
+
+#define VERBOSE_PREFIX_1 " "
+#define VERBOSE_PREFIX_2 " == "
+#define VERBOSE_PREFIX_3 " -- "
+#define VERBOSE_PREFIX_4 " > "
+
+/*! \brief Used for sending a log message
+ This is the standard logger function. Probably the only way you will invoke it would be something like this:
+ ast_log(LOG_WHATEVER, "Problem with the %s Captain. We should get some more. Will %d be enough?\n", "flux capacitor", 10);
+ where WHATEVER is one of ERROR, DEBUG, EVENT, NOTICE, or WARNING depending
+ on which log you wish to output to. These are implemented as macros, that
+ will provide the function with the needed arguments.
+
+ \param level Type of log event
+ \param file Will be provided by the LOG_* macro
+ \param line Will be provided by the LOG_* macro
+ \param function Will be provided by the LOG_* macro
+ \param fmt This is what is important. The format is the same as your favorite breed of printf. You know how that works, right? :-)
+ */
+
+void ast_log(int level, const char *file, int line, const char *function, const char *fmt, ...)
+ __attribute__ ((format (printf, 5, 6)));
+
+void ast_backtrace(void);
+
+/*! \brief Reload logger without rotating log files */
+int logger_reload(void);
+
+void ast_queue_log(const char *queuename, const char *callid, const char *agent, const char *event, const char *fmt, ...)
+ __attribute__ ((format (printf, 5, 6)));
+
+/*! Send a verbose message (based on verbose level)
+ \brief This works like ast_log, but prints verbose messages to the console depending on verbosity level set.
+ ast_verbose(VERBOSE_PREFIX_3 "Whatever %s is happening\n", "nothing");
+ This will print the message to the console if the verbose level is set to a level >= 3
+ Note the abscence of a comma after the VERBOSE_PREFIX_3. This is important.
+ VERBOSE_PREFIX_1 through VERBOSE_PREFIX_3 are defined.
+ */
+void ast_verbose(const char *fmt, ...)
+ __attribute__ ((format (printf, 1, 2)));
+
+int ast_register_verbose(void (*verboser)(const char *string));
+int ast_unregister_verbose(void (*verboser)(const char *string));
+
+void ast_console_puts(const char *string);
+
+void ast_console_puts_mutable(const char *string);
+void ast_console_toggle_mute(int fd, int silent);
+
+#define _A_ __FILE__, __LINE__, __PRETTY_FUNCTION__
+
+#ifdef LOG_DEBUG
+#undef LOG_DEBUG
+#endif
+#define __LOG_DEBUG 0
+#define LOG_DEBUG __LOG_DEBUG, _A_
+
+#ifdef LOG_EVENT
+#undef LOG_EVENT
+#endif
+#define __LOG_EVENT 1
+#define LOG_EVENT __LOG_EVENT, _A_
+
+#ifdef LOG_NOTICE
+#undef LOG_NOTICE
+#endif
+#define __LOG_NOTICE 2
+#define LOG_NOTICE __LOG_NOTICE, _A_
+
+#ifdef LOG_WARNING
+#undef LOG_WARNING
+#endif
+#define __LOG_WARNING 3
+#define LOG_WARNING __LOG_WARNING, _A_
+
+#ifdef LOG_ERROR
+#undef LOG_ERROR
+#endif
+#define __LOG_ERROR 4
+#define LOG_ERROR __LOG_ERROR, _A_
+
+#ifdef LOG_VERBOSE
+#undef LOG_VERBOSE
+#endif
+#define __LOG_VERBOSE 5
+#define LOG_VERBOSE __LOG_VERBOSE, _A_
+
+#ifdef LOG_DTMF
+#undef LOG_DTMF
+#endif
+#define __LOG_DTMF 6
+#define LOG_DTMF __LOG_DTMF, _A_
+
+/*!
+ * \brief Get the debug level for a file
+ * \arg file the filename
+ * \return the debug level
+ */
+unsigned int ast_debug_get_by_file(const char *file);
+
+/*!
+ * \brief Get the debug level for a file
+ * \arg file the filename
+ * \return the debug level
+ */
+unsigned int ast_verbose_get_by_file(const char *file);
+
+/*!
+ * \brief Log a DEBUG message
+ * \param level The minimum value of option_debug for this message
+ * to get logged
+ */
+#define ast_debug(level, ...) do { \
+ if (option_debug >= (level) || (ast_opt_dbg_file && ast_debug_get_by_file(__FILE__) >= (level)) ) \
+ ast_log(LOG_DEBUG, __VA_ARGS__); \
+} while (0)
+
+#define VERBOSITY_ATLEAST(level) (option_verbose >= (level) || (ast_opt_verb_file && ast_verbose_get_by_file(__FILE__) >= (level)))
+
+#define ast_verb(level, ...) do { \
+ if (VERBOSITY_ATLEAST((level)) ) { \
+ if (level >= 4) \
+ ast_verbose(VERBOSE_PREFIX_4 __VA_ARGS__); \
+ else if (level == 3) \
+ ast_verbose(VERBOSE_PREFIX_3 __VA_ARGS__); \
+ else if (level == 2) \
+ ast_verbose(VERBOSE_PREFIX_2 __VA_ARGS__); \
+ else if (level == 1) \
+ ast_verbose(VERBOSE_PREFIX_1 __VA_ARGS__); \
+ else \
+ ast_verbose(__VA_ARGS__); \
+ } \
+} while (0)
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _ASTERISK_LOGGER_H */
diff --git a/trunk/include/asterisk/manager.h b/trunk/include/asterisk/manager.h
new file mode 100644
index 000000000..327f674f8
--- /dev/null
+++ b/trunk/include/asterisk/manager.h
@@ -0,0 +1,211 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2005, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+#ifndef _ASTERISK_MANAGER_H
+#define _ASTERISK_MANAGER_H
+
+#include "asterisk/network.h"
+#include "asterisk/lock.h"
+
+/*!
+ \file
+ \brief The AMI - Asterisk Manager Interface - is a TCP protocol created to
+ manage Asterisk with third-party software.
+
+ Manager protocol packages are text fields of the form a: b. There is
+ always exactly one space after the colon.
+
+\verbatim
+
+ For Actions replies, the first line of the reply is a "Response:" header with
+ values "success", "error" or "follows". "Follows" implies that the
+ response is coming as separate events with the same ActionID. If the
+ Action request has no ActionID, it will be hard matching events
+ to the Action request in the manager client.
+
+ The first header type is the "Event" header. Other headers vary from
+ event to event. Headers end with standard \\r\\n termination.
+ The last line of the manager response or event is an empty line.
+ (\\r\\n)
+
+\endverbatim
+
+ \note Please try to \b re-use \b existing \b headers to simplify manager message parsing in clients.
+ Don't re-use an existing header with a new meaning, please.
+ You can find a reference of standard headers in doc/manager.txt
+
+- \ref manager.c Main manager code file
+ */
+
+#define AMI_VERSION "1.1"
+#define DEFAULT_MANAGER_PORT 5038 /* Default port for Asterisk management via TCP */
+
+/*! \name Manager event classes */
+/*@{ */
+#define EVENT_FLAG_SYSTEM (1 << 0) /* System events such as module load/unload */
+#define EVENT_FLAG_CALL (1 << 1) /* Call event, such as state change, etc */
+#define EVENT_FLAG_LOG (1 << 2) /* Log events */
+#define EVENT_FLAG_VERBOSE (1 << 3) /* Verbose messages */
+#define EVENT_FLAG_COMMAND (1 << 4) /* Ability to read/set commands */
+#define EVENT_FLAG_AGENT (1 << 5) /* Ability to read/set agent info */
+#define EVENT_FLAG_USER (1 << 6) /* Ability to read/set user info */
+#define EVENT_FLAG_CONFIG (1 << 7) /* Ability to modify configurations */
+#define EVENT_FLAG_DTMF (1 << 8) /* Ability to read DTMF events */
+#define EVENT_FLAG_REPORTING (1 << 9) /* Reporting events such as rtcp sent */
+#define EVENT_FLAG_CDR (1 << 10) /* CDR events */
+#define EVENT_FLAG_DIALPLAN (1 << 11) /* Dialplan events (VarSet, NewExten) */
+/*@} */
+
+/*! \brief Export manager structures */
+#define AST_MAX_MANHEADERS 128
+
+/*! \brief Manager Helper Function */
+typedef int (*manager_hook_t)(int, const char *, char *);
+
+
+struct manager_custom_hook {
+ /*! Identifier */
+ char *file;
+ /*! helper function */
+ manager_hook_t helper;
+ /*! Linked list information */
+ AST_RWLIST_ENTRY(manager_custom_hook) list;
+};
+
+/*! \brief Check if AMI is enabled */
+int check_manager_enabled(void);
+
+/*! \brief Check if AMI/HTTP is enabled */
+int check_webmanager_enabled(void);
+
+/*! Add a custom hook to be called when an event is fired
+ \param hook struct manager_custom_hook object to add
+*/
+void ast_manager_register_hook(struct manager_custom_hook *hook);
+
+/*! Delete a custom hook to be called when an event is fired
+ \param hook struct manager_custom_hook object to delete
+*/
+void ast_manager_unregister_hook(struct manager_custom_hook *hook);
+
+struct mansession;
+
+struct message {
+ unsigned int hdrcount;
+ const char *headers[AST_MAX_MANHEADERS];
+};
+
+struct manager_action {
+ /*! Name of the action */
+ const char *action;
+ /*! Short description of the action */
+ const char *synopsis;
+ /*! Detailed description of the action */
+ const char *description;
+ /*! Permission required for action. EVENT_FLAG_* */
+ int authority;
+ /*! Function to be called */
+ int (*func)(struct mansession *s, const struct message *m);
+ /*! For easy linking */
+ AST_RWLIST_ENTRY(manager_action) list;
+};
+
+/*! \brief External routines may register/unregister manager callbacks this way
+ * \note Use ast_manager_register2() to register with help text for new manager commands */
+#define ast_manager_register(a, b, c, d) ast_manager_register2(a, b, c, d, NULL)
+
+
+/*! \brief Register a manager command with the manager interface
+ \param action Name of the requested Action:
+ \param authority Required authority for this command
+ \param func Function to call for this command
+ \param synopsis Help text (one line, up to 30 chars) for CLI manager show commands
+ \param description Help text, several lines
+*/
+int ast_manager_register2(
+ const char *action,
+ int authority,
+ int (*func)(struct mansession *s, const struct message *m),
+ const char *synopsis,
+ const char *description);
+
+/*! \brief Unregister a registred manager command
+ \param action Name of registred Action:
+*/
+int ast_manager_unregister( char *action );
+
+/*!
+ * \brief Verify a session's read permissions against a permission mask.
+ * \param ident session identity
+ * \param perm permission mask to verify
+ * \retval 1 if the session has the permission mask capabilities
+ * \retval 0 otherwise
+ */
+int astman_verify_session_readpermissions(unsigned long ident, int perm);
+
+/*!
+ * \brief Verify a session's write permissions against a permission mask.
+ * \param ident session identity
+ * \param perm permission mask to verify
+ * \retval 1 if the session has the permission mask capabilities, otherwise 0
+ * \retval 0 otherwise
+ */
+int astman_verify_session_writepermissions(unsigned long ident, int perm);
+
+/*! \brief External routines may send asterisk manager events this way
+ * \param category Event category, matches manager authorization
+ \param event Event name
+ \param contents Contents of event
+*/
+
+/* XXX the parser in gcc 2.95 gets confused if you don't put a space
+ * between the last arg before VA_ARGS and the comma */
+#define manager_event(category, event, contents , ...) \
+ __manager_event(category, event, __FILE__, __LINE__, __PRETTY_FUNCTION__, contents , ## __VA_ARGS__)
+
+int __attribute__ ((format(printf, 6, 7))) __manager_event(int category, const char *event,
+ const char *file, int line, const char *func,
+ const char *contents, ...);
+
+/*! \brief Get header from mananger transaction */
+const char *astman_get_header(const struct message *m, char *var);
+
+/*! \brief Get a linked list of the Variable: headers */
+struct ast_variable *astman_get_variables(const struct message *m);
+
+/*! \brief Send error in manager transaction */
+void astman_send_error(struct mansession *s, const struct message *m, char *error);
+
+/*! \brief Send response in manager transaction */
+void astman_send_response(struct mansession *s, const struct message *m, char *resp, char *msg);
+
+/*! \brief Send ack in manager transaction */
+void astman_send_ack(struct mansession *s, const struct message *m, char *msg);
+
+/*! \brief Send ack in manager list transaction */
+void astman_send_listack(struct mansession *s, const struct message *m, char *msg, char *listflag);
+
+void __attribute__ ((format (printf, 2, 3))) astman_append(struct mansession *s, const char *fmt, ...);
+
+/*! \brief Called by Asterisk initialization */
+int init_manager(void);
+
+/*! \brief Called by Asterisk module functions and the CLI command */
+int reload_manager(void);
+
+#endif /* _ASTERISK_MANAGER_H */
diff --git a/trunk/include/asterisk/md5.h b/trunk/include/asterisk/md5.h
new file mode 100644
index 000000000..714267da6
--- /dev/null
+++ b/trunk/include/asterisk/md5.h
@@ -0,0 +1,38 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2005, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*!\file
+ * \brief MD5 digest functions
+ */
+
+#ifndef _ASTERISK_MD5_H
+#define _ASTERISK_MD5_H
+
+struct MD5Context {
+ uint32_t buf[4];
+ uint32_t bits[2];
+ unsigned char in[64];
+};
+
+void MD5Init(struct MD5Context *context);
+void MD5Update(struct MD5Context *context, unsigned char const *buf,
+ unsigned len);
+void MD5Final(unsigned char digest[16], struct MD5Context *context);
+void MD5Transform(uint32_t buf[4], uint32_t const in[16]);
+
+#endif /* _ASTERISK_MD5_H */
diff --git a/trunk/include/asterisk/mod_format.h b/trunk/include/asterisk/mod_format.h
new file mode 100644
index 000000000..c51bf681c
--- /dev/null
+++ b/trunk/include/asterisk/mod_format.h
@@ -0,0 +1,144 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2006, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief Header for providers of file and format handling routines.
+ * Clients of these routines should include "asterisk/file.h" instead.
+ */
+
+#ifndef _ASTERISK_MOD_FORMAT_H
+#define _ASTERISK_MOD_FORMAT_H
+
+#include "asterisk/file.h"
+#include "asterisk/frame.h"
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/*! \brief
+ * Each supported file format is described by the following structure.
+ *
+ * Not all are necessary, the support routine implement default
+ * values for some of them.
+ * A handler typically fills a structure initializing the desired
+ * fields, and then calls ast_format_register() with the (readonly)
+ * structure as an argument.
+ */
+struct ast_format {
+ char name[80]; /*!< Name of format */
+ char exts[80]; /*!< Extensions (separated by | if more than one)
+ this format can read. First is assumed for writing (e.g. .mp3) */
+ int format; /*!< Format of frames it uses/provides (one only) */
+ /*!
+ * \brief Prepare an input stream for playback.
+ * \return 0 on success, -1 on error.
+ * The FILE is already open (in s->f) so this function only needs to perform
+ * any applicable validity checks on the file. If none is required, the
+ * function can be omitted.
+ */
+ int (*open)(struct ast_filestream *s);
+ /*!
+ * \brief Prepare a stream for output, and comment it appropriately if applicable.
+ * \return 0 on success, -1 on error.
+ * Same as the open, the FILE is already open so the function just needs to
+ * prepare any header and other fields, if any.
+ * The function can be omitted if nothing is needed.
+ */
+ int (*rewrite)(struct ast_filestream *s, const char *comment);
+ /*! Write a frame to a channel */
+ int (*write)(struct ast_filestream *, struct ast_frame *);
+ /*! seek num samples into file, whence - like a normal seek but with offset in samples */
+ int (*seek)(struct ast_filestream *, off_t, int);
+ int (*trunc)(struct ast_filestream *fs); /*!< trunc file to current position */
+ off_t (*tell)(struct ast_filestream *fs); /*!< tell current position */
+ /*! Read the next frame from the filestream (if available) and report
+ * when to get next frame (in samples)
+ */
+ struct ast_frame * (*read)(struct ast_filestream *, int *whennext);
+ /*! Do any closing actions, if any. The descriptor and structure are closed
+ * and destroyed by the generic routines, so they must not be done here. */
+ void (*close)(struct ast_filestream *);
+ char * (*getcomment)(struct ast_filestream *); /*!< Retrieve file comment */
+
+ AST_LIST_ENTRY(ast_format) list; /*!< Link */
+
+ /*!
+ * If the handler needs a buffer (for read, typically)
+ * and/or a private descriptor, put here the
+ * required size (in bytes) and the support routine will allocate them
+ * for you, pointed by s->buf and s->private, respectively.
+ * When allocating a buffer, remember to leave AST_FRIENDLY_OFFSET
+ * spare bytes at the bginning.
+ */
+ int buf_size; /*!< size of frame buffer, if any, aligned to 8 bytes. */
+ int desc_size; /*!< size of private descriptor, if any */
+
+ struct ast_module *module;
+};
+
+/*! \brief
+ * This structure is allocated by file.c in one chunk,
+ * together with buf_size and desc_size bytes of memory
+ * to be used for private purposes (e.g. buffers etc.)
+ */
+struct ast_filestream {
+ /*! Everybody reserves a block of AST_RESERVED_POINTERS pointers for us */
+ struct ast_format *fmt; /* need to write to the lock and usecnt */
+ int flags;
+ mode_t mode;
+ char *filename;
+ char *realfilename;
+ /*! Video file stream */
+ struct ast_filestream *vfs;
+ /*! Transparently translate from another format -- just once */
+ struct ast_trans_pvt *trans;
+ struct ast_tranlator_pvt *tr;
+ int lastwriteformat;
+ int lasttimeout;
+ struct ast_channel *owner;
+ FILE *f;
+ struct ast_frame fr; /*!< frame produced by read, typically */
+ char *buf; /*!< buffer pointed to by ast_frame; */
+ void *_private; /*!< pointer to private buffer */
+ const char *orig_chan_name;
+};
+
+/*!
+ * \brief Register a new file format capability.
+ * Adds a format to Asterisk's format abilities.
+ * \retval 0 on success
+ * \retval -1 on failure
+ */
+int __ast_format_register(const struct ast_format *f, struct ast_module *mod);
+#define ast_format_register(f) __ast_format_register(f, ast_module_info->self)
+
+/*!
+ * \brief Unregisters a file format
+ * \param name the name of the format you wish to unregister
+ * Unregisters a format based on the name of the format.
+ * \retval 0 on success
+ * \retval -1 on failure to unregister
+ */
+int ast_format_unregister(const char *name);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _ASTERISK_MOD_FORMAT_H */
diff --git a/trunk/include/asterisk/module.h b/trunk/include/asterisk/module.h
new file mode 100644
index 000000000..2344fe825
--- /dev/null
+++ b/trunk/include/asterisk/module.h
@@ -0,0 +1,421 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2008, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ * Kevin P. Fleming <kpfleming@digium.com>
+ * Luigi Rizzo <rizzo@icir.org>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief Asterisk module definitions.
+ *
+ * This file contains the definitons for functions Asterisk modules should
+ * provide and some other module related functions.
+ */
+
+#ifndef _ASTERISK_MODULE_H
+#define _ASTERISK_MODULE_H
+
+#include "asterisk/utils.h"
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/*! \brief The text the key() function should return. */
+#define ASTERISK_GPL_KEY \
+"This paragraph is copyright (c) 2006 by Digium, Inc. \
+In order for your module to load, it must return this \
+key via a function called \"key\". Any code which \
+includes this paragraph must be licensed under the GNU \
+General Public License version 2 or later (at your \
+option). In addition to Digium's general reservations \
+of rights, Digium expressly reserves the right to \
+allow other parties to license this paragraph under \
+different terms. Any use of Digium, Inc. trademarks or \
+logos (including \"Asterisk\" or \"Digium\") without \
+express written permission of Digium, Inc. is prohibited.\n"
+
+#define AST_MODULE_CONFIG "modules.conf" /*!< \brief Module configuration file */
+
+enum ast_module_unload_mode {
+ AST_FORCE_SOFT = 0, /*!< Softly unload a module, only if not in use */
+ AST_FORCE_FIRM = 1, /*!< Firmly unload a module, even if in use */
+ AST_FORCE_HARD = 2, /*!< as FIRM, plus dlclose() on the module. Not recommended
+ as it may cause crashes */
+};
+
+enum ast_module_load_result {
+ AST_MODULE_LOAD_SUCCESS = 0, /*!< Module loaded and configured */
+ AST_MODULE_LOAD_DECLINE = 1, /*!< Module is not configured */
+ AST_MODULE_LOAD_SKIP = 2, /*!< Module was skipped for some reason */
+ AST_MODULE_LOAD_FAILURE = -1, /*!< Module could not be loaded properly */
+};
+
+/*!
+ * \brief Load a module.
+ * \param resource_name The name of the module to load.
+ *
+ * This function is run by the PBX to load the modules. It performs
+ * all loading and initilization tasks. Basically, to load a module, just
+ * give it the name of the module and it will do the rest.
+ *
+ * \return See possible enum values for ast_module_load_result.
+ */
+enum ast_module_load_result ast_load_resource(const char *resource_name);
+
+/*!
+ * \brief Unload a module.
+ * \param resource_name The name of the module to unload.
+ * \param ast_module_unload_mode The force flag. This should be set using one of the AST_FORCE flags.
+ *
+ * This function unloads a module. It will only unload modules that are not in
+ * use (usecount not zero), unless #AST_FORCE_FIRM or #AST_FORCE_HARD is
+ * specified. Setting #AST_FORCE_FIRM or #AST_FORCE_HARD will unload the
+ * module regardless of consequences (NOT RECOMMENDED).
+ *
+ * \retval 0 on success.
+ * \retval -1 on error.
+ */
+int ast_unload_resource(const char *resource_name, enum ast_module_unload_mode);
+
+/*!
+ * \brief Notify when usecount has been changed.
+ *
+ * This function calulates use counts and notifies anyone trying to keep track
+ * of them. It should be called whenever your module's usecount changes.
+ *
+ * \note The ast_module_user_* functions take care of calling this function for you.
+ */
+void ast_update_use_count(void);
+
+/*!
+ * \brief Ask for a list of modules, descriptions, and use counts.
+ * \param modentry A callback to an updater function.
+ * \param like
+ *
+ * For each of the modules loaded, modentry will be executed with the resource,
+ * description, and usecount values of each particular module.
+ *
+ * \return the number of modules loaded
+ */
+int ast_update_module_list(int (*modentry)(const char *module, const char *description, int usecnt, const char *like),
+ const char *like);
+
+/*!
+ * \brief Check if module with the name given is loaded
+ * \param name Module name, like "chan_sip.so"
+ * \retval 1 if true
+ * \retval 0 if false
+ */
+int ast_module_check(const char *name);
+
+/*!
+ * \brief Add a procedure to be run when modules have been updated.
+ * \param updater The function to run when modules have been updated.
+ *
+ * This function adds the given function to a linked list of functions to be
+ * run when the modules are updated.
+ *
+ * \retval 0 on success
+ * \retval -1 on failure.
+ */
+int ast_loader_register(int (*updater)(void));
+
+/*!
+ * \brief Remove a procedure to be run when modules are updated.
+ * \param updater The updater function to unregister.
+ *
+ * This removes the given function from the updater list.
+ *
+ * \retval 0 on success
+ * \retval -1 on failure.
+ */
+int ast_loader_unregister(int (*updater)(void));
+
+/*!
+ * \brief Run the unload() callback for all loaded modules
+ *
+ * This function should be called when Asterisk is shutting down gracefully.
+ */
+void ast_module_shutdown(void);
+
+/*!
+ * \brief Match modules names for the Asterisk cli.
+ * \param line Unused by this function, but this should be the line we are
+ * matching.
+ * \param word The partial name to match.
+ * \param pos The position the word we are completing is in.
+ * \param state The possible match to return.
+ * \param rpos The position we should be matching. This should be the same as
+ * pos.
+ * \param needsreload This should be 1 if we need to reload this module and 0
+ * otherwise. This function will only return modules that are reloadble
+ * if this is 1.
+ *
+ * \retval A possible completion of the partial match.
+ * \retval NULL if no matches were found.
+ */
+char *ast_module_helper(const char *line, const char *word, int pos, int state, int rpos, int needsreload);
+
+/* Opaque type for module handles generated by the loader */
+
+struct ast_module;
+
+/* User count routines keep track of which channels are using a given module
+ resource. They can help make removing modules safer, particularly if
+ they're in use at the time they have been requested to be removed */
+
+struct ast_module_user;
+struct ast_module_user_list;
+
+/*! \page ModMngmnt The Asterisk Module management interface
+ *
+ * All modules must implement the module API (load, unload...)
+ */
+
+enum ast_module_flags {
+ AST_MODFLAG_DEFAULT = 0,
+ AST_MODFLAG_GLOBAL_SYMBOLS = (1 << 0),
+};
+
+struct ast_module_info {
+
+ /*!
+ * The 'self' pointer for a module; it will be set by the loader before
+ * it calls the module's load_module() entrypoint, and used by various
+ * other macros that need to identify the module.
+ */
+
+ struct ast_module *self;
+ enum ast_module_load_result (*load)(void); /*!< register stuff etc. Optional. */
+ int (*reload)(void); /*!< config etc. Optional. */
+ int (*unload)(void); /*!< unload. called with the module locked */
+ int (*backup_globals)(void); /*!< for embedded modules, backup global data */
+ void (*restore_globals)(void); /*!< for embedded modules, restore global data */
+ const char *name; /*!< name of the module for loader reference and CLI commands */
+ const char *description; /*!< user friendly description of the module. */
+
+ /*!
+ * This holds the ASTERISK_GPL_KEY, signifiying that you agree to the terms of
+ * the Asterisk license as stated in the ASTERISK_GPL_KEY. Your module will not
+ * load if it does not return the EXACT key string.
+ */
+
+ const char *key;
+ unsigned int flags;
+
+ /*! The value of AST_BUILDOPT_SUM when this module was compiled */
+ const char buildopt_sum[33];
+};
+
+void ast_module_register(const struct ast_module_info *);
+void ast_module_unregister(const struct ast_module_info *);
+
+struct ast_module_user *__ast_module_user_add(struct ast_module *, struct ast_channel *);
+void __ast_module_user_remove(struct ast_module *, struct ast_module_user *);
+void __ast_module_user_hangup_all(struct ast_module *);
+
+#define ast_module_user_add(chan) __ast_module_user_add(ast_module_info->self, chan)
+#define ast_module_user_remove(user) __ast_module_user_remove(ast_module_info->self, user)
+#define ast_module_user_hangup_all() __ast_module_user_hangup_all(ast_module_info->self)
+
+struct ast_module *ast_module_ref(struct ast_module *);
+void ast_module_unref(struct ast_module *);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+#define AST_MODULE_INFO(keystr, flags_to_set, desc, load_func, unload_func, reload_func) \
+ static struct ast_module_info __mod_info = { \
+ NULL, \
+ load_func, \
+ reload_func, \
+ unload_func, \
+ AST_MODULE, \
+ NULL, \
+ NULL, \
+ desc, \
+ keystr, \
+ flags_to_set, \
+ AST_BUILDOPT_SUM, \
+ }; \
+ static void __attribute__ ((constructor)) __reg_module(void) \
+ { \
+ ast_module_register(&__mod_info); \
+ } \
+ static void __attribute__ ((destructor)) __unreg_module(void) \
+ { \
+ ast_module_unregister(&__mod_info); \
+ } \
+ const static __attribute__((unused)) struct ast_module_info *ast_module_info = &__mod_info
+
+#define AST_MODULE_INFO_STANDARD(keystr, desc) \
+ AST_MODULE_INFO(keystr, AST_MODFLAG_DEFAULT, desc, \
+ load_module, \
+ unload_module, \
+ NULL \
+ )
+#else /* plain C */
+
+/* forward declare this pointer in modules, so that macro/function
+ calls that need it can get it, since it will actually be declared
+ and populated at the end of the module's source file... */
+const static __attribute__((unused)) struct ast_module_info *ast_module_info;
+
+#if !defined(EMBEDDED_MODULE)
+#define __MODULE_INFO_SECTION
+#define __MODULE_INFO_GLOBALS
+#else
+/*
+ * For embedded modules we need additional information to backup and
+ * restore the global variables in the module itself, so we can unload
+ * reload the module.
+ * EMBEDDED_MODULE is defined as the module name, so the calls to make_var()
+ * below will actually define different symbols for each module.
+ */
+#define __MODULE_INFO_SECTION __attribute__((section(".embed_module")))
+#define __MODULE_INFO_GLOBALS .backup_globals = __backup_globals, .restore_globals = __restore_globals,
+
+#define make_var_sub(mod, type) __ ## mod ## _ ## type
+#define make_var(mod, type) make_var_sub(mod, type)
+
+extern void make_var(EMBEDDED_MODULE, bss_start);
+extern void make_var(EMBEDDED_MODULE, bss_end);
+extern void make_var(EMBEDDED_MODULE, data_start);
+extern void make_var(EMBEDDED_MODULE, data_end);
+
+static void * __attribute__((section(".embed_module"))) __global_backup;
+
+static int __backup_globals(void)
+{
+ size_t data_size = & make_var(EMBEDDED_MODULE, data_end) - & make_var(EMBEDDED_MODULE, data_start);
+
+ if (__global_backup)
+ return 0;
+
+ if (!data_size)
+ return 0;
+
+ if (!(__global_backup = ast_malloc(data_size)))
+ return -1;
+
+ memcpy(__global_backup, & make_var(EMBEDDED_MODULE, data_start), data_size);
+
+ return 0;
+}
+
+static void __restore_globals(void)
+{
+ size_t data_size = & make_var(EMBEDDED_MODULE, data_end) - & make_var(EMBEDDED_MODULE, data_start);
+ size_t bss_size = & make_var(EMBEDDED_MODULE, bss_end) - & make_var(EMBEDDED_MODULE, bss_start);
+
+ if (bss_size)
+ memset(& make_var(EMBEDDED_MODULE, bss_start), 0, bss_size);
+
+ if (!data_size || !__global_backup)
+ return;
+
+ memcpy(& make_var(EMBEDDED_MODULE, data_start), __global_backup, data_size);
+}
+#undef make_var
+#undef make_var_sub
+#endif /* EMBEDDED_MODULE */
+
+#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...) \
+ static struct ast_module_info \
+ __MODULE_INFO_SECTION \
+ __mod_info = { \
+ __MODULE_INFO_GLOBALS \
+ .name = AST_MODULE, \
+ .flags = flags_to_set, \
+ .description = desc, \
+ .key = keystr, \
+ .buildopt_sum = AST_BUILDOPT_SUM, \
+ fields \
+ }; \
+ static void __attribute__ ((constructor)) __reg_module(void) \
+ { \
+ ast_module_register(&__mod_info); \
+ } \
+ static void __attribute__ ((destructor)) __unreg_module(void) \
+ { \
+ ast_module_unregister(&__mod_info); \
+ } \
+ const static struct ast_module_info *ast_module_info = &__mod_info
+
+#define AST_MODULE_INFO_STANDARD(keystr, desc) \
+ AST_MODULE_INFO(keystr, AST_MODFLAG_DEFAULT, desc, \
+ .load = load_module, \
+ .unload = unload_module, \
+ )
+#endif /* plain C */
+
+/*!
+ * \brief Register an application.
+ *
+ * \param app Short name of the application
+ * \param execute a function callback to execute the application. It should return
+ * non-zero if the channel needs to be hung up.
+ * \param synopsis a short description (one line synopsis) of the application
+ * \param description long description with all of the details about the use of
+ * the application
+ *
+ * This registers an application with Asterisk's internal application list.
+ * \note The individual applications themselves are responsible for registering and unregistering
+ * and unregistering their own CLI commands.
+ *
+ * \retval 0 success
+ * \retval -1 failure.
+ */
+#define ast_register_application(app, execute, synopsis, description) ast_register_application2(app, execute, synopsis, description, ast_module_info->self)
+
+/*!
+ * \brief Register an application.
+ *
+ * \param app Short name of the application
+ * \param execute a function callback to execute the application. It should return
+ * non-zero if the channel needs to be hung up.
+ * \param synopsis a short description (one line synopsis) of the application
+ * \param description long description with all of the details about the use of
+ * the application
+ * \param mod module this application belongs to
+ *
+ * This registers an application with Asterisk's internal application list.
+ * \note The individual applications themselves are responsible for registering and unregistering
+ * and unregistering their own CLI commands.
+ *
+ * \retval 0 success
+ * \retval -1 failure.
+ */
+int ast_register_application2(const char *app, int (*execute)(struct ast_channel *, void *),
+ const char *synopsis, const char *description, void *mod);
+
+/*!
+ * \brief Unregister an application
+ *
+ * \param app name of the application (does not have to be the same string as the one that was registered)
+ *
+ * This unregisters an application from Asterisk's internal application list.
+ *
+ * \retval 0 success
+ * \retval -1 failure
+ */
+int ast_unregister_application(const char *app);
+
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _ASTERISK_MODULE_H */
diff --git a/trunk/include/asterisk/monitor.h b/trunk/include/asterisk/monitor.h
new file mode 100644
index 000000000..7f32b6994
--- /dev/null
+++ b/trunk/include/asterisk/monitor.h
@@ -0,0 +1,71 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2005, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief Channel monitoring
+ */
+
+#ifndef _ASTERISK_MONITOR_H
+#define _ASTERISK_MONITOR_H
+
+#include "asterisk/channel.h"
+
+enum AST_MONITORING_STATE {
+ AST_MONITOR_RUNNING,
+ AST_MONITOR_PAUSED
+};
+
+/* Streams recording control */
+#define X_REC_IN 1
+#define X_REC_OUT 2
+#define X_JOIN 4
+
+/*! Responsible for channel monitoring data */
+struct ast_channel_monitor {
+ struct ast_filestream *read_stream;
+ struct ast_filestream *write_stream;
+ char read_filename[FILENAME_MAX];
+ char write_filename[FILENAME_MAX];
+ char filename_base[FILENAME_MAX];
+ int filename_changed;
+ char *format;
+ int joinfiles;
+ enum AST_MONITORING_STATE state;
+ int (*stop)(struct ast_channel *chan, int need_lock);
+};
+
+/* Start monitoring a channel */
+int ast_monitor_start(struct ast_channel *chan, const char *format_spec,
+ const char *fname_base, int need_lock, int stream_action);
+
+/* Stop monitoring a channel */
+int ast_monitor_stop(struct ast_channel *chan, int need_lock);
+
+/* Change monitoring filename of a channel */
+int ast_monitor_change_fname(struct ast_channel *chan,
+ const char *fname_base, int need_lock);
+
+void ast_monitor_setjoinfiles(struct ast_channel *chan, int turnon);
+
+/* Pause monitoring of a channel */
+int ast_monitor_pause(struct ast_channel *chan);
+
+/* Unpause monitoring of a channel */
+int ast_monitor_unpause(struct ast_channel *chan);
+
+#endif /* _ASTERISK_MONITOR_H */
diff --git a/trunk/include/asterisk/musiconhold.h b/trunk/include/asterisk/musiconhold.h
new file mode 100644
index 000000000..480f2ff8e
--- /dev/null
+++ b/trunk/include/asterisk/musiconhold.h
@@ -0,0 +1,59 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2005, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief Music on hold handling
+ */
+
+#ifndef _ASTERISK_MOH_H
+#define _ASTERISK_MOH_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/*!
+ * \brief Turn on music on hold on a given channel
+ *
+ * \param chan The channel structure that will get music on hold
+ * \param mclass The class to use if the musicclass is not currently set on
+ * the channel structure.
+ * \param interpclass The class to use if the musicclass is not currently set on
+ * the channel structure or in the mclass argument.
+ *
+ * \retval Zero on success
+ * \retval non-zero on failure
+ */
+int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass);
+
+/*! Turn off music on hold on a given channel */
+void ast_moh_stop(struct ast_channel *chan);
+
+void ast_install_music_functions(int (*start_ptr)(struct ast_channel *, const char *, const char *),
+ void (*stop_ptr)(struct ast_channel *),
+ void (*cleanup_ptr)(struct ast_channel *));
+
+void ast_uninstall_music_functions(void);
+
+void ast_moh_cleanup(struct ast_channel *chan);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _ASTERISK_MOH_H */
diff --git a/trunk/include/asterisk/netsock.h b/trunk/include/asterisk/netsock.h
new file mode 100644
index 000000000..2aeb803b4
--- /dev/null
+++ b/trunk/include/asterisk/netsock.h
@@ -0,0 +1,70 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2005, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ * Kevin P. Fleming <kpfleming@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief Network socket handling
+ */
+
+#ifndef _ASTERISK_NETSOCK_H
+#define _ASTERISK_NETSOCK_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+#include "asterisk/network.h"
+#include "asterisk/io.h"
+#include "asterisk/astobj.h"
+
+struct ast_netsock;
+
+struct ast_netsock_list;
+
+struct ast_netsock_list *ast_netsock_list_alloc(void);
+
+int ast_netsock_init(struct ast_netsock_list *list);
+
+struct ast_netsock *ast_netsock_bind(struct ast_netsock_list *list, struct io_context *ioc,
+ const char *bindinfo, int defaultport, int tos, int cos, ast_io_cb callback, void *data);
+
+struct ast_netsock *ast_netsock_bindaddr(struct ast_netsock_list *list, struct io_context *ioc,
+ struct sockaddr_in *bindaddr, int tos, int cos, ast_io_cb callback, void *data);
+
+int ast_netsock_free(struct ast_netsock_list *list, struct ast_netsock *netsock);
+
+int ast_netsock_release(struct ast_netsock_list *list);
+
+struct ast_netsock *ast_netsock_find(struct ast_netsock_list *list,
+ struct sockaddr_in *sa);
+
+int ast_netsock_set_qos(int netsocket, int tos, int cos, const char *desc);
+
+int ast_netsock_sockfd(const struct ast_netsock *ns);
+
+const struct sockaddr_in *ast_netsock_boundaddr(const struct ast_netsock *ns);
+
+void *ast_netsock_data(const struct ast_netsock *ns);
+
+void ast_netsock_unref(struct ast_netsock *ns);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _ASTERISK_NETSOCK_H */
diff --git a/trunk/include/asterisk/network.h b/trunk/include/asterisk/network.h
new file mode 100644
index 000000000..00aebe45f
--- /dev/null
+++ b/trunk/include/asterisk/network.h
@@ -0,0 +1,98 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2007, Digium, Inc.
+ *
+ * Luigi Rizzo
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief Wrapper for network related headers,
+ * masking differences between various operating systems.
+ * On passing, we also provide here trivial functions or
+ * other simple wrappers to network-related functions.
+ */
+
+#ifndef _ASTERISK_NETWORK_H
+#define _ASTERISK_NETWORK_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/*
+ * Include relevant network headers.
+ * Our preferred choice are the standard BSD/linux/unix headers.
+ * Missing them (e.g. for solaris or various windows environments),
+ * we resort to whatever we find around, and provide local definitions
+ * for the missing bits.
+ */
+#ifdef HAVE_ARPA_INET_H
+#include <netinet/in.h>
+#include <arpa/inet.h> /* include early to override inet_ntoa */
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/tcp.h>
+#include <netdb.h>
+#include <sys/socket.h>
+#elif defined(HAVE_WINSOCK_H)
+#include <winsock.h>
+typedef int socklen_t;
+#elif defined(HAVE_WINSOCK2_H)
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#else
+#error "don't know how to handle network functions here."
+#endif
+
+#ifndef HAVE_INET_ATON
+int inet_aton(const char *cp, struct in_addr *pin);
+#endif
+
+#ifndef IFNAMSIZ
+#define IFNAMSIZ 16
+#endif
+
+#ifndef MAXHOSTNAMELEN
+#define MAXHOSTNAMELEN 256
+#endif
+
+/*!
+ * \brief thread-safe replacement for inet_ntoa().
+ *
+ * \note It is very important to note that even though this is a thread-safe
+ * replacement for inet_ntoa(), it is *not* reentrant. In a single
+ * thread, the result from a previous call to this function is no longer
+ * valid once it is called again. If the result from multiple calls to
+ * this function need to be kept or used at once, then the result must be
+ * copied to a local buffer before calling this function again.
+ */
+const char *ast_inet_ntoa(struct in_addr ia);
+
+#ifdef inet_ntoa
+#undef inet_ntoa
+#endif
+#define inet_ntoa __dont__use__inet_ntoa__use__ast_inet_ntoa__instead__
+
+/*! \brief Compares the source address and port of two sockaddr_in */
+static force_inline int inaddrcmp(const struct sockaddr_in *sin1, const struct sockaddr_in *sin2)
+{
+ return ((sin1->sin_addr.s_addr != sin2->sin_addr.s_addr)
+ || (sin1->sin_port != sin2->sin_port));
+}
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _ASTERISK_NETWORK_H */
diff --git a/trunk/include/asterisk/options.h b/trunk/include/asterisk/options.h
new file mode 100644
index 000000000..f974ca2c9
--- /dev/null
+++ b/trunk/include/asterisk/options.h
@@ -0,0 +1,137 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2005, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief Options provided by main asterisk program
+ */
+
+#ifndef _ASTERISK_OPTIONS_H
+#define _ASTERISK_OPTIONS_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+#define AST_CACHE_DIR_LEN 512
+#define AST_FILENAME_MAX 80
+
+/*! \ingroup main_options */
+enum ast_option_flags {
+ /*! Allow \#exec in config files */
+ AST_OPT_FLAG_EXEC_INCLUDES = (1 << 0),
+ /*! Do not fork() */
+ AST_OPT_FLAG_NO_FORK = (1 << 1),
+ /*! Keep quiet */
+ AST_OPT_FLAG_QUIET = (1 << 2),
+ /*! Console mode */
+ AST_OPT_FLAG_CONSOLE = (1 << 3),
+ /*! Run in realtime Linux priority */
+ AST_OPT_FLAG_HIGH_PRIORITY = (1 << 4),
+ /*! Initialize keys for RSA authentication */
+ AST_OPT_FLAG_INIT_KEYS = (1 << 5),
+ /*! Remote console */
+ AST_OPT_FLAG_REMOTE = (1 << 6),
+ /*! Execute an asterisk CLI command upon startup */
+ AST_OPT_FLAG_EXEC = (1 << 7),
+ /*! Don't use termcap colors */
+ AST_OPT_FLAG_NO_COLOR = (1 << 8),
+ /*! Are we fully started yet? */
+ AST_OPT_FLAG_FULLY_BOOTED = (1 << 9),
+ /*! Trascode via signed linear */
+ AST_OPT_FLAG_TRANSCODE_VIA_SLIN = (1 << 10),
+ /*! Dump core on a seg fault */
+ AST_OPT_FLAG_DUMP_CORE = (1 << 12),
+ /*! Cache sound files */
+ AST_OPT_FLAG_CACHE_RECORD_FILES = (1 << 13),
+ /*! Display timestamp in CLI verbose output */
+ AST_OPT_FLAG_TIMESTAMP = (1 << 14),
+ /*! Override config */
+ AST_OPT_FLAG_OVERRIDE_CONFIG = (1 << 15),
+ /*! Reconnect */
+ AST_OPT_FLAG_RECONNECT = (1 << 16),
+ /*! Transmit Silence during Record() */
+ AST_OPT_FLAG_TRANSMIT_SILENCE = (1 << 17),
+ /*! Suppress some warnings */
+ AST_OPT_FLAG_DONT_WARN = (1 << 18),
+ /*! End CDRs before the 'h' extension */
+ AST_OPT_FLAG_END_CDR_BEFORE_H_EXTEN = (1 << 19),
+ /*! Use Zaptel Timing for generators if available */
+ AST_OPT_FLAG_INTERNAL_TIMING = (1 << 20),
+ /*! Always fork, even if verbose or debug settings are non-zero */
+ AST_OPT_FLAG_ALWAYS_FORK = (1 << 21),
+ /*! Disable log/verbose output to remote consoles */
+ AST_OPT_FLAG_MUTE = (1 << 22),
+ /*! There is a per-file debug setting */
+ AST_OPT_FLAG_DEBUG_FILE = (1 << 23),
+ /*! There is a per-file verbose setting */
+ AST_OPT_FLAG_VERBOSE_FILE = (1 << 24),
+};
+
+/*! These are the options that set by default when Asterisk starts */
+#define AST_DEFAULT_OPTIONS AST_OPT_FLAG_TRANSCODE_VIA_SLIN
+
+#define ast_opt_exec_includes ast_test_flag(&ast_options, AST_OPT_FLAG_EXEC_INCLUDES)
+#define ast_opt_no_fork ast_test_flag(&ast_options, AST_OPT_FLAG_NO_FORK)
+#define ast_opt_quiet ast_test_flag(&ast_options, AST_OPT_FLAG_QUIET)
+#define ast_opt_console ast_test_flag(&ast_options, AST_OPT_FLAG_CONSOLE)
+#define ast_opt_high_priority ast_test_flag(&ast_options, AST_OPT_FLAG_HIGH_PRIORITY)
+#define ast_opt_init_keys ast_test_flag(&ast_options, AST_OPT_FLAG_INIT_KEYS)
+#define ast_opt_remote ast_test_flag(&ast_options, AST_OPT_FLAG_REMOTE)
+#define ast_opt_exec ast_test_flag(&ast_options, AST_OPT_FLAG_EXEC)
+#define ast_opt_no_color ast_test_flag(&ast_options, AST_OPT_FLAG_NO_COLOR)
+#define ast_fully_booted ast_test_flag(&ast_options, AST_OPT_FLAG_FULLY_BOOTED)
+#define ast_opt_transcode_via_slin ast_test_flag(&ast_options, AST_OPT_FLAG_TRANSCODE_VIA_SLIN)
+#define ast_opt_dump_core ast_test_flag(&ast_options, AST_OPT_FLAG_DUMP_CORE)
+#define ast_opt_cache_record_files ast_test_flag(&ast_options, AST_OPT_FLAG_CACHE_RECORD_FILES)
+#define ast_opt_timestamp ast_test_flag(&ast_options, AST_OPT_FLAG_TIMESTAMP)
+#define ast_opt_override_config ast_test_flag(&ast_options, AST_OPT_FLAG_OVERRIDE_CONFIG)
+#define ast_opt_reconnect ast_test_flag(&ast_options, AST_OPT_FLAG_RECONNECT)
+#define ast_opt_transmit_silence ast_test_flag(&ast_options, AST_OPT_FLAG_TRANSMIT_SILENCE)
+#define ast_opt_dont_warn ast_test_flag(&ast_options, AST_OPT_FLAG_DONT_WARN)
+#define ast_opt_end_cdr_before_h_exten ast_test_flag(&ast_options, AST_OPT_FLAG_END_CDR_BEFORE_H_EXTEN)
+#define ast_opt_internal_timing ast_test_flag(&ast_options, AST_OPT_FLAG_INTERNAL_TIMING)
+#define ast_opt_always_fork ast_test_flag(&ast_options, AST_OPT_FLAG_ALWAYS_FORK)
+#define ast_opt_mute ast_test_flag(&ast_options, AST_OPT_FLAG_MUTE)
+#define ast_opt_dbg_file ast_test_flag(&ast_options, AST_OPT_FLAG_DEBUG_FILE)
+#define ast_opt_verb_file ast_test_flag(&ast_options, AST_OPT_FLAG_VERBOSE_FILE)
+
+extern struct ast_flags ast_options;
+
+extern int option_verbose;
+extern int option_maxfiles; /*!< Max number of open file handles (files, sockets) */
+extern int option_debug; /*!< Debugging */
+extern int option_maxcalls; /*!< Maximum number of simultaneous channels */
+extern double option_maxload;
+#if defined(HAVE_SYSINFO)
+extern long option_minmemfree; /*!< Minimum amount of free system memory - stop accepting calls if free memory falls below this watermark */
+#endif
+extern char defaultlanguage[];
+
+extern struct timeval ast_startuptime;
+extern struct timeval ast_lastreloadtime;
+extern pid_t ast_mainpid;
+
+extern char record_cache_dir[AST_CACHE_DIR_LEN];
+
+extern int ast_language_is_prefix;
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _ASTERISK_OPTIONS_H */
diff --git a/trunk/include/asterisk/paths.h b/trunk/include/asterisk/paths.h
new file mode 100644
index 000000000..c161c284d
--- /dev/null
+++ b/trunk/include/asterisk/paths.h
@@ -0,0 +1,39 @@
+/*
+ * Asterisk -- A telephony toolkit for Linux.
+ *
+ * Paths to configurable Asterisk directories
+ *
+ * Copyright (C) 1999-2006, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License
+ */
+
+/*! \file
+ * \brief Asterisk file paths, configured in asterisk.conf
+ */
+
+#ifndef _ASTERISK_PATHS_H
+#define _ASTERISK_PATHS_H
+
+extern const char *ast_config_AST_CONFIG_DIR;
+extern const char *ast_config_AST_CONFIG_FILE;
+extern const char *ast_config_AST_MODULE_DIR;
+extern const char *ast_config_AST_SPOOL_DIR;
+extern const char *ast_config_AST_MONITOR_DIR;
+extern const char *ast_config_AST_VAR_DIR;
+extern const char *ast_config_AST_DATA_DIR;
+extern const char *ast_config_AST_LOG_DIR;
+extern const char *ast_config_AST_AGI_DIR;
+extern const char *ast_config_AST_DB;
+extern const char *ast_config_AST_KEY_DIR;
+extern const char *ast_config_AST_PID;
+extern const char *ast_config_AST_SOCKET;
+extern const char *ast_config_AST_RUN_DIR;
+extern const char *ast_config_AST_RUN_GROUP;
+extern const char *ast_config_AST_RUN_USER;
+extern const char *ast_config_AST_SYSTEM_NAME;
+
+#endif /* _ASTERISK_PATHS_H */
diff --git a/trunk/include/asterisk/pbx.h b/trunk/include/asterisk/pbx.h
new file mode 100644
index 000000000..1082c74b2
--- /dev/null
+++ b/trunk/include/asterisk/pbx.h
@@ -0,0 +1,978 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2006, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief Core PBX routines and definitions.
+ */
+
+#ifndef _ASTERISK_PBX_H
+#define _ASTERISK_PBX_H
+
+#include "asterisk/sched.h"
+#include "asterisk/chanvars.h"
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+#define AST_MAX_APP 32 /*!< Max length of an application */
+
+#define AST_PBX_KEEP 0
+#define AST_PBX_REPLACE 1
+
+/*! \brief Special return values from applications to the PBX { */
+#define AST_PBX_HANGUP -1 /*!< Jump to the 'h' exten */
+#define AST_PBX_OK 0 /*!< No errors */
+#define AST_PBX_ERROR 1 /*!< Jump to the 'e' exten */
+#define AST_PBX_KEEPALIVE 10 /*!< Destroy the thread, but don't hang up the channel */
+#define AST_PBX_NO_HANGUP_PEER 11
+/*! } */
+
+#define PRIORITY_HINT -1 /*!< Special Priority for a hint */
+
+/*! \brief Extension states
+ \note States can be combined
+ - \ref AstExtState
+*/
+enum ast_extension_states {
+ AST_EXTENSION_REMOVED = -2, /*!< Extension removed */
+ AST_EXTENSION_DEACTIVATED = -1, /*!< Extension hint removed */
+ AST_EXTENSION_NOT_INUSE = 0, /*!< No device INUSE or BUSY */
+ AST_EXTENSION_INUSE = 1 << 0, /*!< One or more devices INUSE */
+ AST_EXTENSION_BUSY = 1 << 1, /*!< All devices BUSY */
+ AST_EXTENSION_UNAVAILABLE = 1 << 2, /*!< All devices UNAVAILABLE/UNREGISTERED */
+ AST_EXTENSION_RINGING = 1 << 3, /*!< All devices RINGING */
+ AST_EXTENSION_ONHOLD = 1 << 4, /*!< All devices ONHOLD */
+};
+
+
+struct ast_context;
+struct ast_exten;
+struct ast_include;
+struct ast_ignorepat;
+struct ast_sw;
+
+/*! \brief Typedef for devicestate and hint callbacks */
+typedef int (*ast_state_cb_type)(char *context, char* id, enum ast_extension_states state, void *data);
+
+/*! \brief Data structure associated with a custom dialplan function */
+struct ast_custom_function {
+ const char *name; /*!< Name */
+ const char *synopsis; /*!< Short description for "show functions" */
+ const char *desc; /*!< Help text that explains it all */
+ const char *syntax; /*!< Syntax description */
+ int (*read)(struct ast_channel *, const char *, char *, char *, size_t); /*!< Read function, if read is supported */
+ int (*write)(struct ast_channel *, const char *, char *, const char *); /*!< Write function, if write is supported */
+ struct ast_module *mod; /*!< Module this custom function belongs to */
+ AST_RWLIST_ENTRY(ast_custom_function) acflist;
+};
+
+/*! \brief All switch functions have the same interface, so define a type for them */
+typedef int (ast_switch_f)(struct ast_channel *chan, const char *context,
+ const char *exten, int priority, const char *callerid, const char *data);
+
+/*!< Data structure associated with an Asterisk switch */
+struct ast_switch {
+ AST_LIST_ENTRY(ast_switch) list;
+ const char *name; /*!< Name of the switch */
+ const char *description; /*!< Description of the switch */
+
+ ast_switch_f *exists;
+ ast_switch_f *canmatch;
+ ast_switch_f *exec;
+ ast_switch_f *matchmore;
+};
+
+struct ast_timing {
+ int hastime; /*!< If time construct exists */
+ unsigned int monthmask; /*!< Mask for month */
+ unsigned int daymask; /*!< Mask for date */
+ unsigned int dowmask; /*!< Mask for day of week (mon-sun) */
+ unsigned int minmask[24]; /*!< Mask for minute */
+};
+
+int ast_build_timing(struct ast_timing *i, const char *info);
+int ast_check_timing(const struct ast_timing *i);
+
+struct ast_pbx {
+ int dtimeout; /*!< Timeout between digits (seconds) */
+ int rtimeout; /*!< Timeout for response (seconds) */
+};
+
+
+/*!
+ * \brief Register an alternative dialplan switch
+ *
+ * \param sw switch to register
+ *
+ * This function registers a populated ast_switch structure with the
+ * asterisk switching architecture.
+ *
+ * \return 0 on success, and other than 0 on failure
+ */
+int ast_register_switch(struct ast_switch *sw);
+
+/*!
+ * \brief Unregister an alternative switch
+ *
+ * \param sw switch to unregister
+ *
+ * Unregisters a switch from asterisk.
+ *
+ * \return nothing
+ */
+void ast_unregister_switch(struct ast_switch *sw);
+
+/*!
+ * \brief Look up an application
+ *
+ * \param app name of the app
+ *
+ * This function searches for the ast_app structure within
+ * the apps that are registered for the one with the name
+ * you passed in.
+ *
+ * \return the ast_app structure that matches on success, or NULL on failure
+ */
+struct ast_app *pbx_findapp(const char *app);
+
+/*!
+ * \brief Execute an application
+ *
+ * \param c channel to execute on
+ * \param app which app to execute
+ * \param data the data passed into the app
+ *
+ * This application executes an application on a given channel. It
+ * saves the stack and executes the given application passing in
+ * the given data.
+ *
+ * \return 0 on success, and -1 on failure
+ */
+int pbx_exec(struct ast_channel *c, struct ast_app *app, void *data);
+
+/*!
+ * \brief Register a new context
+ *
+ * \param extcontexts pointer to the ast_context structure pointer
+ * \param name name of the new context
+ * \param registrar registrar of the context
+ *
+ * This will first search for a context with your name. If it exists already, it will not
+ * create a new one. If it does not exist, it will create a new one with the given name
+ * and registrar.
+ *
+ * \return NULL on failure, and an ast_context structure on success
+ */
+struct ast_context *ast_context_create(struct ast_context **extcontexts, const char *name, const char *registrar);
+
+/*!
+ * \brief Register a new context or find an existing one
+ *
+ * \param extcontexts pointer to the ast_context structure pointer
+ * \param name name of the new context
+ * \param registrar registrar of the context
+ *
+ * This will first search for a context with your name. If it exists already, it will not
+ * create a new one. If it does not exist, it will create a new one with the given name
+ * and registrar.
+ *
+ * \return NULL on failure, and an ast_context structure on success
+ */
+struct ast_context *ast_context_find_or_create(struct ast_context **extcontexts, const char *name, const char *registrar);
+
+/*!
+ * \brief Merge the temporary contexts into a global contexts list and delete from the
+ * global list the ones that are being added
+ *
+ * \param extcontexts pointer to the ast_context structure pointer
+ * \param registrar of the context; if it's set the routine will delete all contexts
+ * that belong to that registrar; if NULL only the contexts that are specified
+ * in extcontexts
+ */
+void ast_merge_contexts_and_delete(struct ast_context **extcontexts, const char *registrar);
+
+/*!
+ * \brief Destroy a context (matches the specified context (or ANY context if NULL)
+ *
+ * \param con context to destroy
+ * \param registrar who registered it
+ *
+ * You can optionally leave out either parameter. It will find it
+ * based on either the ast_context or the registrar name.
+ *
+ * \return nothing
+ */
+void ast_context_destroy(struct ast_context *con, const char *registrar);
+
+/*!
+ * \brief Find a context
+ *
+ * \param name name of the context to find
+ *
+ * Will search for the context with the given name.
+ *
+ * \return the ast_context on success, NULL on failure.
+ */
+struct ast_context *ast_context_find(const char *name);
+
+/*! \brief The result codes when starting the PBX on a channelwith \see ast_pbx_start.
+ AST_PBX_CALL_LIMIT refers to the maxcalls call limit in asterisk.conf
+ */
+enum ast_pbx_result {
+ AST_PBX_SUCCESS = 0,
+ AST_PBX_FAILED = -1,
+ AST_PBX_CALL_LIMIT = -2,
+};
+
+/*!
+ * \brief Create a new thread and start the PBX
+ *
+ * \param c channel to start the pbx on
+ *
+ * \see ast_pbx_run for a synchronous function to run the PBX in the
+ * current thread, as opposed to starting a new one.
+ *
+ * \retval Zero on success
+ * \retval non-zero on failure
+ */
+enum ast_pbx_result ast_pbx_start(struct ast_channel *c);
+
+/*!
+ * \brief Execute the PBX in the current thread
+ *
+ * \param c channel to run the pbx on
+ *
+ * This executes the PBX on a given channel. It allocates a new
+ * PBX structure for the channel, and provides all PBX functionality.
+ * See ast_pbx_start for an asynchronous function to run the PBX in a
+ * new thread as opposed to the current one.
+ *
+ * \retval Zero on success
+ * \retval non-zero on failure
+ */
+enum ast_pbx_result ast_pbx_run(struct ast_channel *c);
+
+/*!
+ * \brief Add and extension to an extension context.
+ *
+ * \param context context to add the extension to
+ * \param replace
+ * \param extension extension to add
+ * \param priority priority level of extension addition
+ * \param label extension label
+ * \param callerid pattern to match CallerID, or NULL to match any CallerID
+ * \param application application to run on the extension with that priority level
+ * \param data data to pass to the application
+ * \param datad
+ * \param registrar who registered the extension
+ *
+ * \retval 0 success
+ * \retval -1 failure
+ */
+int ast_add_extension(const char *context, int replace, const char *extension,
+ int priority, const char *label, const char *callerid,
+ const char *application, void *data, void (*datad)(void *), const char *registrar);
+
+/*!
+ * \brief Add an extension to an extension context, this time with an ast_context *.
+ *
+ * \note For details about the arguments, check ast_add_extension()
+ */
+int ast_add_extension2(struct ast_context *con, int replace, const char *extension,
+ int priority, const char *label, const char *callerid,
+ const char *application, void *data, void (*datad)(void *), const char *registrar);
+
+
+/*!
+ * \brief Uses hint and devicestate callback to get the state of an extension
+ *
+ * \param c this is not important
+ * \param context which context to look in
+ * \param exten which extension to get state
+ *
+ * \return extension state as defined in the ast_extension_states enum
+ */
+int ast_extension_state(struct ast_channel *c, const char *context, const char *exten);
+
+/*!
+ * \brief Return string representation of the state of an extension
+ *
+ * \param extension_state is the numerical state delivered by ast_extension_state
+ *
+ * \return the state of an extension as string
+ */
+const char *ast_extension_state2str(int extension_state);
+
+/*!
+ * \brief Registers a state change callback
+ *
+ * \param context which context to look in
+ * \param exten which extension to get state
+ * \param callback callback to call if state changed
+ * \param data to pass to callback
+ *
+ * The callback is called if the state of an extension is changed.
+ *
+ * \retval -1 on failure
+ * \retval ID on success
+ */
+int ast_extension_state_add(const char *context, const char *exten,
+ ast_state_cb_type callback, void *data);
+
+/*!
+ * \brief Deletes a registered state change callback by ID
+ *
+ * \param id of the callback to delete
+ * \param callback callback
+ *
+ * Removes the callback from list of callbacks
+ *
+ * \retval 0 success
+ * \retval -1 failure
+ */
+int ast_extension_state_del(int id, ast_state_cb_type callback);
+
+/*!
+ * \brief If an extension hint exists, return non-zero
+ *
+ * \param hint buffer for hint
+ * \param maxlen size of hint buffer
+ * \param name buffer for name portion of hint
+ * \param maxnamelen size of name buffer
+ * \param c this is not important
+ * \param context which context to look in
+ * \param exten which extension to search for
+ *
+ * \return If an extension within the given context with the priority PRIORITY_HINT
+ * is found a non zero value will be returned.
+ * Otherwise, 0 is returned.
+ */
+int ast_get_hint(char *hint, int maxlen, char *name, int maxnamelen,
+ struct ast_channel *c, const char *context, const char *exten);
+
+/*!
+ * \brief Determine whether an extension exists
+ *
+ * \param c this is not important
+ * \param context which context to look in
+ * \param exten which extension to search for
+ * \param priority priority of the action within the extension
+ * \param callerid callerid to search for
+ *
+ * \return If an extension within the given context(or callerid) with the given priority
+ * is found a non zero value will be returned. Otherwise, 0 is returned.
+ */
+int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten,
+ int priority, const char *callerid);
+
+/*!
+ * \brief Find the priority of an extension that has the specified label
+ *
+ * \param c this is not important
+ * \param context which context to look in
+ * \param exten which extension to search for
+ * \param label label of the action within the extension to match to priority
+ * \param callerid callerid to search for
+ *
+ * \retval the priority which matches the given label in the extension
+ * \retval -1 if not found.
+ */
+int ast_findlabel_extension(struct ast_channel *c, const char *context,
+ const char *exten, const char *label, const char *callerid);
+
+/*!
+ * \brief Find the priority of an extension that has the specified label
+ *
+ * \note This function is the same as ast_findlabel_extension, except that it accepts
+ * a pointer to an ast_context structure to specify the context instead of the
+ * name of the context. Otherwise, the functions behave the same.
+ */
+int ast_findlabel_extension2(struct ast_channel *c, struct ast_context *con,
+ const char *exten, const char *label, const char *callerid);
+
+/*!
+ * \brief Looks for a valid matching extension
+ *
+ * \param c not really important
+ * \param context context to serach within
+ * \param exten extension to check
+ * \param priority priority of extension path
+ * \param callerid callerid of extension being searched for
+ *
+ * \return If "exten" *could be* a valid extension in this context with or without
+ * some more digits, return non-zero. Basically, when this returns 0, no matter
+ * what you add to exten, it's not going to be a valid extension anymore
+ */
+int ast_canmatch_extension(struct ast_channel *c, const char *context,
+ const char *exten, int priority, const char *callerid);
+
+/*!
+ * \brief Looks to see if adding anything to this extension might match something. (exists ^ canmatch)
+ *
+ * \param c not really important XXX
+ * \param context context to serach within
+ * \param exten extension to check
+ * \param priority priority of extension path
+ * \param callerid callerid of extension being searched for
+ *
+ * \return If "exten" *could match* a valid extension in this context with
+ * some more digits, return non-zero. Does NOT return non-zero if this is
+ * an exact-match only. Basically, when this returns 0, no matter
+ * what you add to exten, it's not going to be a valid extension anymore
+ */
+int ast_matchmore_extension(struct ast_channel *c, const char *context,
+ const char *exten, int priority, const char *callerid);
+
+/*!
+ * \brief Determine if a given extension matches a given pattern (in NXX format)
+ *
+ * \param pattern pattern to match
+ * \param extension extension to check against the pattern.
+ *
+ * Checks whether or not the given extension matches the given pattern.
+ *
+ * \retval 1 on match
+ * \retval 0 on failure
+ */
+int ast_extension_match(const char *pattern, const char *extension);
+
+int ast_extension_close(const char *pattern, const char *data, int needmore);
+
+/*!
+ * \brief Determine if one extension should match before another
+ *
+ * \param a extension to compare with b
+ * \param b extension to compare with a
+ *
+ * Checks whether or extension a should match before extension b
+ *
+ * \retval 0 if the two extensions have equal matching priority
+ * \retval 1 on a > b
+ * \retval -1 on a < b
+ */
+int ast_extension_cmp(const char *a, const char *b);
+
+/*!
+ * \brief Launch a new extension (i.e. new stack)
+ *
+ * \param c not important
+ * \param context which context to generate the extension within
+ * \param exten new extension to add
+ * \param priority priority of new extension
+ * \param callerid callerid of extension
+ * \param found
+ * \param combined_find_spawn
+ *
+ * This adds a new extension to the asterisk extension list.
+ *
+ * \retval 0 on success
+ * \retval -1 on failure.
+ */
+int ast_spawn_extension(struct ast_channel *c, const char *context,
+ const char *exten, int priority, const char *callerid, int *found, int combined_find_spawn);
+
+/*!
+ * \brief Add a context include
+ *
+ * \param context context to add include to
+ * \param include new include to add
+ * \param registrar who's registering it
+ *
+ * Adds an include taking a char * string as the context parameter
+ *
+ * \retval 0 on success
+ * \retval -1 on error
+*/
+int ast_context_add_include(const char *context, const char *include,
+ const char *registrar);
+
+/*!
+ * \brief Add a context include
+ *
+ * \param con context to add the include to
+ * \param include include to add
+ * \param registrar who registered the context
+ *
+ * Adds an include taking a struct ast_context as the first parameter
+ *
+ * \retval 0 on success
+ * \retval -1 on failure
+ */
+int ast_context_add_include2(struct ast_context *con, const char *include,
+ const char *registrar);
+
+/*!
+ * \brief Remove a context include
+ *
+ * \note See ast_context_add_include for information on arguments
+ *
+ * \retval 0 on success
+ * \retval -1 on failure
+ */
+int ast_context_remove_include(const char *context, const char *include,
+ const char *registrar);
+
+/*!
+ * \brief Removes an include by an ast_context structure
+ *
+ * \note See ast_context_add_include2 for information on arguments
+ *
+ * \retval 0 on success
+ * \retval -1 on success
+ */
+int ast_context_remove_include2(struct ast_context *con, const char *include,
+ const char *registrar);
+
+/*!
+ * \brief Verifies includes in an ast_contect structure
+ *
+ * \param con context in which to verify the includes
+ *
+ * \retval 0 if no problems found
+ * \retval -1 if there were any missing context
+ */
+int ast_context_verify_includes(struct ast_context *con);
+
+/*!
+ * \brief Add a switch
+ *
+ * \param context context to which to add the switch
+ * \param sw switch to add
+ * \param data data to pass to switch
+ * \param eval whether to evaluate variables when running switch
+ * \param registrar whoever registered the switch
+ *
+ * This function registers a switch with the asterisk switch architecture
+ *
+ * \retval 0 on success
+ * \retval -1 on failure
+ */
+int ast_context_add_switch(const char *context, const char *sw, const char *data,
+ int eval, const char *registrar);
+
+/*!
+ * \brief Adds a switch (first param is a ast_context)
+ *
+ * \note See ast_context_add_switch() for argument information, with the exception of
+ * the first argument. In this case, it's a pointer to an ast_context structure
+ * as opposed to the name.
+ */
+int ast_context_add_switch2(struct ast_context *con, const char *sw, const char *data,
+ int eval, const char *registrar);
+
+/*!
+ * \brief Remove a switch
+ *
+ * Removes a switch with the given parameters
+ *
+ * \retval 0 on success
+ * \retval -1 on failure
+ */
+int ast_context_remove_switch(const char *context, const char *sw,
+ const char *data, const char *registrar);
+
+int ast_context_remove_switch2(struct ast_context *con, const char *sw,
+ const char *data, const char *registrar);
+
+/*!
+ * \brief Simply remove extension from context
+ *
+ * \param context context to remove extension from
+ * \param extension which extension to remove
+ * \param priority priority of extension to remove
+ * \param registrar registrar of the extension
+ *
+ * This function removes an extension from a given context.
+ *
+ * \retval 0 on success
+ * \retval -1 on failure
+ */
+int ast_context_remove_extension(const char *context, const char *extension, int priority,
+ const char *registrar);
+
+int ast_context_remove_extension2(struct ast_context *con, const char *extension,
+ int priority, const char *registrar);
+
+/*!
+ * \brief Add an ignorepat
+ *
+ * \param context which context to add the ignorpattern to
+ * \param ignorepat ignorepattern to set up for the extension
+ * \param registrar registrar of the ignore pattern
+ *
+ * Adds an ignore pattern to a particular context.
+ *
+ * \retval 0 on success
+ * \retval -1 on failure
+ */
+int ast_context_add_ignorepat(const char *context, const char *ignorepat, const char *registrar);
+
+int ast_context_add_ignorepat2(struct ast_context *con, const char *ignorepat, const char *registrar);
+
+/*
+ * \brief Remove an ignorepat
+ *
+ * \param context context from which to remove the pattern
+ * \param ignorepat the pattern to remove
+ * \param registrar the registrar of the ignore pattern
+ *
+ * This removes the given ignorepattern
+ *
+ * \retval 0 on success
+ * \retval -1 on failure
+ */
+int ast_context_remove_ignorepat(const char *context, const char *ignorepat, const char *registrar);
+
+int ast_context_remove_ignorepat2(struct ast_context *con, const char *ignorepat, const char *registrar);
+
+/*!
+ * \brief Checks to see if a number should be ignored
+ *
+ * \param context context to search within
+ * \param pattern to check whether it should be ignored or not
+ *
+ * Check if a number should be ignored with respect to dialtone cancellation.
+ *
+ * \retval 0 if the pattern should not be ignored
+ * \retval non-zero if the pattern should be ignored
+ */
+int ast_ignore_pattern(const char *context, const char *pattern);
+
+/* Locking functions for outer modules, especially for completion functions */
+
+/*!
+ * \brief Write locks the context list
+ *
+ * \retval 0 on success
+ * \retval -1 on error
+ */
+int ast_wrlock_contexts(void);
+
+/*!
+ * \brief Read locks the context list
+ *
+ * \retval 0 on success
+ * \retval -1 on error
+ */
+int ast_rdlock_contexts(void);
+
+/*!
+ * \brief Unlocks contexts
+ *
+ * \retval 0 on success
+ * \retval -1 on failure
+ */
+int ast_unlock_contexts(void);
+
+/*!
+ * \brief Write locks a given context
+ *
+ * \param con context to lock
+ *
+ * \retval 0 on success
+ * \retval -1 on failure
+ */
+int ast_wrlock_context(struct ast_context *con);
+
+/*!
+ * \brief Read locks a given context
+ *
+ * \param con context to lock
+ *
+ * \retval 0 on success
+ * \retval -1 on failure
+ */
+int ast_rdlock_context(struct ast_context *con);
+
+/*!
+ * \retval Unlocks the given context
+ *
+ * \param con context to unlock
+ *
+ * \retval 0 on success
+ * \retval -1 on failure
+ */
+int ast_unlock_context(struct ast_context *con);
+
+/*!
+ * \brief locks the macrolock in the given given context
+ *
+ * \param macrocontext name of the macro-context to lock
+ *
+ * Locks the given macro-context to ensure only one thread (call) can execute it at a time
+ *
+ * \retval 0 on success
+ * \retval -1 on failure
+ */
+int ast_context_lockmacro(const char *macrocontext);
+
+/*!
+ * \brief Unlocks the macrolock in the given context
+ *
+ * \param macrocontext name of the macro-context to unlock
+ *
+ * Unlocks the given macro-context so that another thread (call) can execute it
+ *
+ * \retval 0 on success
+ * \retval -1 on failure
+ */
+int ast_context_unlockmacro(const char *macrocontext);
+
+int ast_async_goto(struct ast_channel *chan, const char *context, const char *exten, int priority);
+
+int ast_async_goto_by_name(const char *chan, const char *context, const char *exten, int priority);
+
+/*! Synchronously or asynchronously make an outbound call and send it to a
+ particular extension */
+int ast_pbx_outgoing_exten(const char *type, int format, void *data, int timeout, const char *context, const char *exten, int priority, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel);
+
+/*! Synchronously or asynchronously make an outbound call and send it to a
+ particular application with given extension */
+int ast_pbx_outgoing_app(const char *type, int format, void *data, int timeout, const char *app, const char *appdata, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel);
+
+/*!
+ * \brief Evaluate a condition
+ *
+ * \retval 0 if the condition is NULL or of zero length
+ * \retval int If the string is an integer, the integer representation of
+ * the integer is returned
+ * \retval 1 Any other non-empty string
+ */
+int pbx_checkcondition(const char *condition);
+
+/*! @name
+ * Functions for returning values from structures */
+/*! @{ */
+const char *ast_get_context_name(struct ast_context *con);
+const char *ast_get_extension_name(struct ast_exten *exten);
+struct ast_context *ast_get_extension_context(struct ast_exten *exten);
+const char *ast_get_include_name(struct ast_include *include);
+const char *ast_get_ignorepat_name(struct ast_ignorepat *ip);
+const char *ast_get_switch_name(struct ast_sw *sw);
+const char *ast_get_switch_data(struct ast_sw *sw);
+/*! @} */
+
+/*! @name Other Extension stuff */
+/*! @{ */
+int ast_get_extension_priority(struct ast_exten *exten);
+int ast_get_extension_matchcid(struct ast_exten *e);
+const char *ast_get_extension_cidmatch(struct ast_exten *e);
+const char *ast_get_extension_app(struct ast_exten *e);
+const char *ast_get_extension_label(struct ast_exten *e);
+void *ast_get_extension_app_data(struct ast_exten *e);
+/*! @} */
+
+/*! @name Registrar info functions ... */
+/*! @{ */
+const char *ast_get_context_registrar(struct ast_context *c);
+const char *ast_get_extension_registrar(struct ast_exten *e);
+const char *ast_get_include_registrar(struct ast_include *i);
+const char *ast_get_ignorepat_registrar(struct ast_ignorepat *ip);
+const char *ast_get_switch_registrar(struct ast_sw *sw);
+/*! @} */
+
+/* Walking functions ... */
+struct ast_context *ast_walk_contexts(struct ast_context *con);
+struct ast_exten *ast_walk_context_extensions(struct ast_context *con,
+ struct ast_exten *priority);
+struct ast_exten *ast_walk_extension_priorities(struct ast_exten *exten,
+ struct ast_exten *priority);
+struct ast_include *ast_walk_context_includes(struct ast_context *con,
+ struct ast_include *inc);
+struct ast_ignorepat *ast_walk_context_ignorepats(struct ast_context *con,
+ struct ast_ignorepat *ip);
+struct ast_sw *ast_walk_context_switches(struct ast_context *con, struct ast_sw *sw);
+
+/*!
+ * \note Will lock the channel.
+ */
+int pbx_builtin_serialize_variables(struct ast_channel *chan, struct ast_str **buf);
+
+/*!
+ * \note Will lock the channel.
+ */
+const char *pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name);
+
+/*!
+ * \note Will lock the channel.
+ */
+void pbx_builtin_pushvar_helper(struct ast_channel *chan, const char *name, const char *value);
+
+/*!
+ * \note Will lock the channel.
+ */
+void pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value);
+
+/*!
+ * \note Will lock the channel.
+ */
+void pbx_retrieve_variable(struct ast_channel *c, const char *var, char **ret, char *workspace, int workspacelen, struct varshead *headp);
+void pbx_builtin_clear_globals(void);
+
+/*!
+ * \note Will lock the channel.
+ */
+int pbx_builtin_setvar(struct ast_channel *chan, void *data);
+
+int pbx_builtin_raise_exception(struct ast_channel *chan, void *data);
+
+void pbx_substitute_variables_helper(struct ast_channel *c,const char *cp1,char *cp2,int count);
+void pbx_substitute_variables_varshead(struct varshead *headp, const char *cp1, char *cp2, int count);
+
+int ast_extension_patmatch(const char *pattern, const char *data);
+
+/*! Set "autofallthrough" flag, if newval is <0, does not acutally set. If
+ set to 1, sets to auto fall through. If newval set to 0, sets to no auto
+ fall through (reads extension instead). Returns previous value. */
+int pbx_set_autofallthrough(int newval);
+
+/*! Set "extenpatternmatchnew" flag, if newval is <0, does not acutally set. If
+ set to 1, sets to use the new Trie-based pattern matcher. If newval set to 0, sets to use
+ the old linear-search algorithm. Returns previous value. */
+int pbx_set_extenpatternmatchnew(int newval);
+
+/*!
+ * \note This function will handle locking the channel as needed.
+ */
+int ast_goto_if_exists(struct ast_channel *chan, const char *context, const char *exten, int priority);
+
+/*!
+ * \note I can find neither parsable nor parseable at dictionary.com,
+ * but google gives me 169000 hits for parseable and only 49,800
+ * for parsable
+ *
+ * \note This function will handle locking the channel as needed.
+ */
+int ast_parseable_goto(struct ast_channel *chan, const char *goto_string);
+
+/*!
+ * \note This function will handle locking the channel as needed.
+ */
+int ast_explicit_goto(struct ast_channel *chan, const char *context, const char *exten, int priority);
+
+/*!
+ * \note This function will handle locking the channel as needed.
+ */
+int ast_async_goto_if_exists(struct ast_channel *chan, const char *context, const char *exten, int priority);
+
+struct ast_custom_function* ast_custom_function_find(const char *name);
+
+/*!
+ * \brief Unregister a custom function
+ */
+int ast_custom_function_unregister(struct ast_custom_function *acf);
+
+/*!
+ * \brief Register a custom function
+ */
+#define ast_custom_function_register(acf) __ast_custom_function_register(acf, ast_module_info->self)
+
+/*!
+ * \brief Register a custom function
+ */
+int __ast_custom_function_register(struct ast_custom_function *acf, struct ast_module *mod);
+
+/*!
+ * \brief Retrieve the number of active calls
+ */
+int ast_active_calls(void);
+
+/*!
+ * \brief Retrieve the total number of calls processed through the PBX since last restart
+ */
+int ast_processed_calls(void);
+
+/*!
+ * \brief executes a read operation on a function
+ *
+ * \param chan Channel to execute on
+ * \param function Data containing the function call string (will be modified)
+ * \param workspace A pointer to safe memory to use for a return value
+ * \param len the number of bytes in workspace
+ *
+ * This application executes a function in read mode on a given channel.
+ *
+ * \return zero on success, non-zero on failure
+ */
+int ast_func_read(struct ast_channel *chan, const char *function, char *workspace, size_t len);
+
+/*!
+ * \brief executes a write operation on a function
+ *
+ * \param chan Channel to execute on
+ * \param function Data containing the function call string (will be modified)
+ * \param value A value parameter to pass for writing
+ *
+ * This application executes a function in write mode on a given channel.
+ *
+ * \return zero on success, non-zero on failure
+ */
+int ast_func_write(struct ast_channel *chan, const char *function, const char *value);
+
+/*!
+ * When looking up extensions, we can have different requests
+ * identified by the 'action' argument, as follows.
+ * Note that the coding is such that the low 4 bits are the
+ * third argument to extension_match_core.
+ */
+
+enum ext_match_t {
+ E_MATCHMORE = 0x00, /* extension can match but only with more 'digits' */
+ E_CANMATCH = 0x01, /* extension can match with or without more 'digits' */
+ E_MATCH = 0x02, /* extension is an exact match */
+ E_MATCH_MASK = 0x03, /* mask for the argument to extension_match_core() */
+ E_SPAWN = 0x12, /* want to spawn an extension. Requires exact match */
+ E_FINDLABEL = 0x22 /* returns the priority for a given label. Requires exact match */
+};
+
+#define STATUS_NO_CONTEXT 1
+#define STATUS_NO_EXTENSION 2
+#define STATUS_NO_PRIORITY 3
+#define STATUS_NO_LABEL 4
+#define STATUS_SUCCESS 5
+#define AST_PBX_MAX_STACK 128
+
+/* request and result for pbx_find_extension */
+struct pbx_find_info {
+#if 0
+ const char *context;
+ const char *exten;
+ int priority;
+#endif
+
+ char *incstack[AST_PBX_MAX_STACK]; /* filled during the search */
+ int stacklen; /* modified during the search */
+ int status; /* set on return */
+ struct ast_switch *swo; /* set on return */
+ const char *data; /* set on return */
+ const char *foundcontext; /* set on return */
+};
+
+struct ast_exten *pbx_find_extension(struct ast_channel *chan,
+ struct ast_context *bypass, struct pbx_find_info *q,
+ const char *context, const char *exten, int priority,
+ const char *label, const char *callerid, enum ext_match_t action);
+
+
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _ASTERISK_PBX_H */
diff --git a/trunk/include/asterisk/plc.h b/trunk/include/asterisk/plc.h
new file mode 100644
index 000000000..cd650012c
--- /dev/null
+++ b/trunk/include/asterisk/plc.h
@@ -0,0 +1,153 @@
+/*! \file
+ * \brief SpanDSP - a series of DSP components for telephony
+ *
+ * plc.h
+ *
+ * \author Steve Underwood <steveu@coppice.org>
+ *
+ * Copyright (C) 2004 Steve Underwood
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * This version may be optionally licenced under the GNU LGPL licence.
+ *
+ * A license has been granted to Digium (via disclaimer) for the use of
+ * this code.
+ */
+
+
+#if !defined(_PLC_H_)
+#define _PLC_H_
+
+/* solaris used to #include <sys/int_types.h> */
+
+/*! \page plc_page Packet loss concealment
+\section plc_page_sec_1 What does it do?
+The packet loss concealment module provides a suitable synthetic fill-in signal,
+to minimise the audible effect of lost packets in VoIP applications. It is not
+tied to any particular codec, and could be used with almost any codec which does not
+specify its own procedure for packet loss concealment.
+
+Where a codec specific concealment procedure exists, the algorithm is usually built
+around knowledge of the characteristics of the particular codec. It will, therefore,
+generally give better results for that particular codec than this generic concealer will.
+
+\section plc_page_sec_2 How does it work?
+While good packets are being received, the plc_rx() routine keeps a record of the trailing
+section of the known speech signal. If a packet is missed, plc_fillin() is called to produce
+a synthetic replacement for the real speech signal. The average mean difference function
+(AMDF) is applied to the last known good signal, to determine its effective pitch.
+Based on this, the last pitch period of signal is saved. Essentially, this cycle of speech
+will be repeated over and over until the real speech resumes. However, several refinements
+are needed to obtain smooth pleasant sounding results.
+
+- The two ends of the stored cycle of speech will not always fit together smoothly. This can
+ cause roughness, or even clicks, at the joins between cycles. To soften this, the
+ 1/4 pitch period of real speech preceeding the cycle to be repeated is blended with the last
+ 1/4 pitch period of the cycle to be repeated, using an overlap-add (OLA) technique (i.e.
+ in total, the last 5/4 pitch periods of real speech are used).
+
+- The start of the synthetic speech will not always fit together smoothly with the tail of
+ real speech passed on before the erasure was identified. Ideally, we would like to modify
+ the last 1/4 pitch period of the real speech, to blend it into the synthetic speech. However,
+ it is too late for that. We could have delayed the real speech a little, but that would
+ require more buffer manipulation, and hurt the efficiency of the no-lost-packets case
+ (which we hope is the dominant case). Instead we use a degenerate form of OLA to modify
+ the start of the synthetic data. The last 1/4 pitch period of real speech is time reversed,
+ and OLA is used to blend it with the first 1/4 pitch period of synthetic speech. The result
+ seems quite acceptable.
+
+- As we progress into the erasure, the chances of the synthetic signal being anything like
+ correct steadily fall. Therefore, the volume of the synthesized signal is made to decay
+ linearly, such that after 50ms of missing audio it is reduced to silence.
+
+- When real speech resumes, an extra 1/4 pitch period of sythetic speech is blended with the
+ start of the real speech. If the erasure is small, this smoothes the transition. If the erasure
+ is long, and the synthetic signal has faded to zero, the blending softens the start up of the
+ real signal, avoiding a kind of "click" or "pop" effect that might occur with a sudden onset.
+
+\section plc_page_sec_3 How do I use it?
+Before audio is processed, call plc_init() to create an instance of the packet loss
+concealer. For each received audio packet that is acceptable (i.e. not including those being
+dropped for being too late) call plc_rx() to record the content of the packet. Note this may
+modify the packet a little after a period of packet loss, to blend real synthetic data smoothly.
+When a real packet is not available in time, call plc_fillin() to create a sythetic substitute.
+That's it!
+*/
+
+/*! Minimum allowed pitch (66 Hz) */
+#define PLC_PITCH_MIN 120
+/*! Maximum allowed pitch (200 Hz) */
+#define PLC_PITCH_MAX 40
+/*! Maximum pitch OLA window */
+#define PLC_PITCH_OVERLAP_MAX (PLC_PITCH_MIN >> 2)
+/*! The length over which the AMDF function looks for similarity (20 ms) */
+#define CORRELATION_SPAN 160
+/*! History buffer length. The buffer much also be at leat 1.25 times
+ PLC_PITCH_MIN, but that is much smaller than the buffer needs to be for
+ the pitch assessment. */
+#define PLC_HISTORY_LEN (CORRELATION_SPAN + PLC_PITCH_MIN)
+
+typedef struct
+{
+ /*! Consecutive erased samples */
+ int missing_samples;
+ /*! Current offset into pitch period */
+ int pitch_offset;
+ /*! Pitch estimate */
+ int pitch;
+ /*! Buffer for a cycle of speech */
+ float pitchbuf[PLC_PITCH_MIN];
+ /*! History buffer */
+ int16_t history[PLC_HISTORY_LEN];
+ /*! Current pointer into the history buffer */
+ int buf_ptr;
+} plc_state_t;
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*! Process a block of received audio samples.
+ \brief Process a block of received audio samples.
+ \param s The packet loss concealer context.
+ \param amp The audio sample buffer.
+ \param len The number of samples in the buffer.
+ \return The number of samples in the buffer. */
+int plc_rx(plc_state_t *s, int16_t amp[], int len);
+
+/*! Fill-in a block of missing audio samples.
+ \brief Fill-in a block of missing audio samples.
+ \param s The packet loss concealer context.
+ \param amp The audio sample buffer.
+ \param len The number of samples to be synthesised.
+ \return The number of samples synthesized. */
+int plc_fillin(plc_state_t *s, int16_t amp[], int len);
+
+/*! Process a block of received V.29 modem audio samples.
+ \brief Process a block of received V.29 modem audio samples.
+ \param s The packet loss concealer context.
+ \return A pointer to the he packet loss concealer context. */
+plc_state_t *plc_init(plc_state_t *s);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/*- End of file ------------------------------------------------------------*/
diff --git a/trunk/include/asterisk/poll-compat.h b/trunk/include/asterisk/poll-compat.h
new file mode 100644
index 000000000..5f795a894
--- /dev/null
+++ b/trunk/include/asterisk/poll-compat.h
@@ -0,0 +1,111 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ */
+
+/*---------------------------------------------------------------------------*\
+ $Id$
+
+ NAME
+
+ poll - select(2)-based poll() emulation function for BSD systems.
+
+ SYNOPSIS
+ #include "poll.h"
+
+ struct pollfd
+ {
+ int fd;
+ short events;
+ short revents;
+ }
+
+ int poll (struct pollfd *pArray, unsigned long n_fds, int timeout)
+
+ DESCRIPTION
+
+ This file, and the accompanying "poll.c", implement the System V
+ poll(2) system call for BSD systems (which typically do not provide
+ poll()). Poll() provides a method for multiplexing input and output
+ on multiple open file descriptors; in traditional BSD systems, that
+ capability is provided by select(). While the semantics of select()
+ differ from those of poll(), poll() can be readily emulated in terms
+ of select() -- which is how this function is implemented.
+
+ REFERENCES
+ Stevens, W. Richard. Unix Network Programming. Prentice-Hall, 1990.
+
+ NOTES
+ 1. This software requires an ANSI C compiler.
+
+ LICENSE
+
+ This software is released under the following license:
+
+ Copyright (c) 1995-2002 Brian M. Clapper
+ All rights reserved.
+
+ Redistribution and use in source and binary forms are
+ permitted provided that: (1) source distributions retain
+ this entire copyright notice and comment; (2) modifications
+ made to the software are prominently mentioned, and a copy
+ of the original software (or a pointer to its location) are
+ included; and (3) distributions including binaries display
+ the following acknowledgement: "This product includes
+ software developed by Brian M. Clapper <bmc@clapper.org>"
+ in the documentation or other materials provided with the
+ distribution. The name of the author may not be used to
+ endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ PARTICULAR PURPOSE.
+
+ Effectively, this means you can do what you want with the software
+ except remove this notice or take advantage of the author's name.
+ If you modify the software and redistribute your modified version,
+ you must indicate that your version is a modification of the
+ original, and you must provide either a pointer to or a copy of the
+ original.
+\*---------------------------------------------------------------------------*/
+
+#ifndef _POLL_EMUL_H_
+#define _POLL_EMUL_H_
+
+#define POLLIN 0x01
+#define POLLPRI 0x02
+#define POLLOUT 0x04
+#define POLLERR 0x08
+#define POLLHUP 0x10
+#define POLLNVAL 0x20
+
+struct pollfd
+{
+ int fd;
+ short events;
+ short revents;
+};
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#if (__STDC__ > 0) || defined(__cplusplus)
+extern int poll (struct pollfd *pArray, unsigned long n_fds, int timeout);
+#else
+extern int poll();
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _POLL_EMUL_H_ */
diff --git a/trunk/include/asterisk/privacy.h b/trunk/include/asterisk/privacy.h
new file mode 100644
index 000000000..686a14d75
--- /dev/null
+++ b/trunk/include/asterisk/privacy.h
@@ -0,0 +1,46 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2005, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief Persistant data storage (akin to *doze registry)
+ */
+
+#ifndef _ASTERISK_PRIVACY_H
+#define _ASTERISK_PRIVACY_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+#define AST_PRIVACY_DENY (1 << 0) /* Don't bother ringing, send to voicemail */
+#define AST_PRIVACY_ALLOW (1 << 1) /* Pass directly to me */
+#define AST_PRIVACY_KILL (1 << 2) /* Play anti-telemarketer message and hangup */
+#define AST_PRIVACY_TORTURE (1 << 3) /* Send directly to tele-torture */
+#define AST_PRIVACY_UNKNOWN (1 << 16)
+
+int ast_privacy_check(char *dest, char *cid);
+
+int ast_privacy_set(char *dest, char *cid, int status);
+
+int ast_privacy_reset(char *dest);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _ASTERISK_PRIVACY_H */
diff --git a/trunk/include/asterisk/pval.h b/trunk/include/asterisk/pval.h
new file mode 100644
index 000000000..edfd647b3
--- /dev/null
+++ b/trunk/include/asterisk/pval.h
@@ -0,0 +1,273 @@
+#ifndef _ASTERISK_PVAL_H
+#define _ASTERISK_PVAL_H
+
+
+typedef enum
+{
+ PV_WORD, /* an ident, string, name, label, etc. A user-supplied string. */ /* 0 */
+ PV_MACRO, /* 1 */
+ PV_CONTEXT, /* 2 */
+ PV_MACRO_CALL, /* 3 */
+ PV_APPLICATION_CALL, /* 4 */
+ PV_CASE, /* 5 */
+ PV_PATTERN, /* 6 */
+ PV_DEFAULT, /* 7 */
+ PV_CATCH, /* 8 */
+ PV_SWITCHES, /* 9 */
+ PV_ESWITCHES, /* 10 */
+ PV_INCLUDES, /* 11 */
+ PV_STATEMENTBLOCK, /* 12 */
+ PV_VARDEC, /* you know, var=val; */ /* 13 */
+ PV_GOTO, /* 14 */
+ PV_LABEL, /* 15 */
+ PV_FOR, /* 16 */
+ PV_WHILE, /* 17 */
+ PV_BREAK, /* 18 */
+ PV_RETURN, /* 19 */
+ PV_CONTINUE, /* 20 */
+ PV_IF, /* 21 */
+ PV_IFTIME, /* 22 */
+ PV_RANDOM, /* 23 */
+ PV_SWITCH, /* 24 */
+ PV_EXTENSION, /* 25 */
+ PV_IGNOREPAT, /* 26 */
+ PV_GLOBALS, /* 27 */
+ PV_LOCALVARDEC, /* 28 */
+} pvaltype;
+
+/* why this horrible mess? It's always been a tradeoff-- tons of structs,
+ each storing it's specific lists of goodies, or a 'simple' single struct,
+ with lots of fields, that catches all uses at once. Either you have a long
+ list of struct names and subnames, or you have a long list of field names,
+ and where/how they are used. I'm going with a single struct, using unions
+ to reduce storage. Some simple generalizations, and a long list of types,
+ and a book about what is used with what types.... Sorry!
+*/
+
+struct pval
+{
+ pvaltype type;
+ int startline;
+ int endline;
+ int startcol;
+ int endcol;
+ char *filename;
+
+ union
+ {
+ char *str; /* wow, used almost everywhere! */
+ struct pval *list; /* used in SWITCHES, ESWITCHES, INCLUDES, STATEMENTBLOCK, GOTO */
+ struct pval *statements;/* used in EXTENSION */
+ char *for_init; /* used in FOR */
+ } u1;
+ struct pval *u1_last; /* to build in-order lists -- looks like we only need one */
+
+ union
+ {
+ struct pval *arglist; /* used in macro_call, application_call, MACRO def, also attached to PWORD, the 4 timevals for includes */
+ struct pval *statements; /* used in case, default, catch, while's statement, CONTEXT elements, GLOBALS */
+ char *val; /* used in VARDEC */
+ char *for_test; /* used in FOR */
+ int label_in_case; /* a boolean for LABELs */
+ struct pval *goto_target; /* used in GOTO */
+ } u2;
+
+ union
+ {
+ char *for_inc; /* used in FOR */
+ struct pval *else_statements; /* used in IF */
+ struct pval *macro_statements; /* used in MACRO */
+ int abstract; /* used for context 1=abstract; 2=extend; 3=both */
+ char *hints; /* used in EXTENSION */
+ int goto_target_in_case; /* used in GOTO */
+ struct ael_extension *compiled_label;
+ struct pval *extend; /* to link extended contexts to the 'original' */
+ } u3;
+
+ union
+ {
+ struct pval *for_statements; /* used in PV_FOR */
+ int regexten; /* used in EXTENSION */
+ } u4;
+
+ struct pval *next; /* the pval at the end of this ptr will ALWAYS be of the same type as this one!
+ EXCEPT for objects of the different types, that are in the same list, like contexts & macros, etc */
+
+ struct pval *dad; /* the 'container' of this struct instance */
+ struct pval *prev; /* the opposite of the 'next' pointer */
+} ;
+
+
+typedef struct pval pval;
+
+#ifndef AAL_ARGCHECK
+/* for the time being, short circuit all the AAL related structures
+ without permanently removing the code; after/during the AAL
+ development, this code can be properly re-instated
+*/
+
+/* null definitions for structs passed down the infrastructure */
+struct argapp
+{
+ struct argapp *next;
+};
+
+#endif
+
+struct ast_context;
+
+#ifdef AAL_ARGCHECK
+int option_matches_j( struct argdesc *should, pval *is, struct argapp *app);
+int option_matches( struct argdesc *should, pval *is, struct argapp *app);
+int ael_is_funcname(char *name);
+#endif
+
+int do_pbx_load_module(void);
+int count_labels_in_current_context(char *label);
+int check_app_args(pval *appcall, pval *arglist, struct argapp *app);
+void check_pval(pval *item, struct argapp *apps, int in_globals);
+void check_pval_item(pval *item, struct argapp *apps, int in_globals);
+void check_switch_expr(pval *item, struct argapp *apps);
+void ast_expr_register_extra_error_info(char *errmsg);
+void ast_expr_clear_extra_error_info(void);
+int ast_expr(char *expr, char *buf, int length, struct ast_channel *chan);
+struct pval *find_macro(char *name);
+struct pval *find_context(char *name);
+struct pval *find_context(char *name);
+struct pval *find_macro(char *name);
+struct ael_priority *new_prio(void);
+struct ael_extension *new_exten(void);
+void linkprio(struct ael_extension *exten, struct ael_priority *prio);
+void destroy_extensions(struct ael_extension *exten);
+/* static void linkexten(struct ael_extension *exten, struct ael_extension *add);
+ static void gen_prios(struct ael_extension *exten, char *label, pval *statement, struct ael_extension *mother_exten, struct ast_context *context ); */
+void set_priorities(struct ael_extension *exten);
+void add_extensions(struct ael_extension *exten);
+void ast_compile_ael2(struct ast_context **local_contexts, struct pval *root);
+void destroy_pval(pval *item);
+void destroy_pval_item(pval *item);
+int is_float(char *arg );
+int is_int(char *arg );
+int is_empty(char *arg);
+
+/* PVAL PI */
+
+
+pval *pvalCreateNode( pvaltype type );
+pvaltype pvalObjectGetType( pval *p );
+
+void pvalWordSetString( pval *p, char *str);
+char *pvalWordGetString( pval *p );
+
+void pvalMacroSetName( pval *p, char *name);
+char *pvalMacroGetName( pval *p );
+void pvalMacroSetArglist( pval *p, pval *arglist );
+void pvalMacroAddArg( pval *p, pval *arg );
+pval *pvalMacroWalkArgs( pval *p, pval **arg );
+void pvalMacroAddStatement( pval *p, pval *statement );
+pval *pvalMacroWalkStatements( pval *p, pval **next_statement );
+
+void pvalContextSetName( pval *p, char *name);
+char *pvalContextGetName( pval *p );
+void pvalContextSetAbstract( pval *p );
+void pvalContextUnsetAbstract( pval *p );
+int pvalContextGetAbstract( pval *p );
+void pvalContextAddStatement( pval *p, pval *statement);
+pval *pvalContextWalkStatements( pval *p, pval **statements );
+
+void pvalMacroCallSetMacroName( pval *p, char *name );
+char* pvalMacroCallGetMacroName( pval *p );
+void pvalMacroCallSetArglist( pval *p, pval *arglist );
+void pvalMacroCallAddArg( pval *p, pval *arg );
+pval *pvalMacroCallWalkArgs( pval *p, pval **args );
+
+void pvalAppCallSetAppName( pval *p, char *name );
+char* pvalAppCallGetAppName( pval *p );
+void pvalAppCallSetArglist( pval *p, pval *arglist );
+void pvalAppCallAddArg( pval *p, pval *arg );
+pval *pvalAppCallWalkArgs( pval *p, pval **args );
+
+void pvalCasePatSetVal( pval *p, char *val );
+char* pvalCasePatGetVal( pval *p );
+void pvalCasePatDefAddStatement( pval *p, pval *statement );
+pval *pvalCasePatDefWalkStatements( pval *p, pval **statement );
+
+void pvalCatchSetExtName( pval *p, char *name );
+char* pvalCatchGetExtName( pval *p );
+void pvalCatchSetStatement( pval *p, pval *statement );
+pval *pvalCatchGetStatement( pval *p );
+
+void pvalSwitchesAddSwitch( pval *p, char *name );
+char* pvalSwitchesWalkNames( pval *p, pval **next_item );
+void pvalESwitchesAddSwitch( pval *p, char *name );
+char* pvalESwitchesWalkNames( pval *p, pval **next_item );
+
+void pvalIncludesAddInclude( pval *p, const char *include );
+
+void pvalIncludesAddIncludeWithTimeConstraints( pval *p, const char *include, char *hour_range, char *dom_range, char *dow_range, char *month_range );
+void pvalIncludeGetTimeConstraints( pval *p, char **hour_range, char **dom_range, char **dow_range, char **month_range );
+char* pvalIncludesWalk( pval *p, pval **next_item );
+
+void pvalStatementBlockAddStatement( pval *p, pval *statement);
+pval *pvalStatementBlockWalkStatements( pval *p, pval **next_statement);
+
+void pvalVarDecSetVarname( pval *p, char *name );
+void pvalVarDecSetValue( pval *p, char *value );
+char* pvalVarDecGetVarname( pval *p );
+char* pvalVarDecGetValue( pval *p );
+
+void pvalGotoSetTarget( pval *p, char *context, char *exten, char *label );
+void pvalGotoGetTarget( pval *p, char **context, char **exten, char **label );
+
+void pvalLabelSetName( pval *p, char *name );
+char* pvalLabelGetName( pval *p );
+
+void pvalForSetInit( pval *p, char *init );
+void pvalForSetTest( pval *p, char *test );
+void pvalForSetInc( pval *p, char *inc );
+void pvalForSetStatement( pval *p, pval *statement );
+char* pvalForGetInit( pval *p );
+char* pvalForGetTest( pval *p );
+char* pvalForGetInc( pval *p );
+pval* pvalForGetStatement( pval *p );
+
+
+void pvalIfSetCondition( pval *p, char *expr );
+char* pvalIfGetCondition( pval *p );
+void pvalIfTimeSetCondition( pval *p, char *hour_range, char *dow_range, char *dom_range, char *mon_range ); /* time range format: 24-hour format begin-end|dow range|dom range|month range */
+void pvalIfTimeGetCondition( pval *p, char **hour_range, char **dow_range, char **dom_range, char **month_range );
+void pvalRandomSetCondition( pval *p, char *percent );
+char* pvalRandomGetCondition( pval *p );
+void pvalConditionalSetThenStatement( pval *p, pval *statement );
+void pvalConditionalSetElseStatement( pval *p, pval *statement );
+pval* pvalConditionalGetThenStatement( pval *p );
+pval* pvalConditionalGetElseStatement( pval *p );
+
+void pvalSwitchSetTestexpr( pval *p, char *expr );
+char* pvalSwitchGetTestexpr( pval *p );
+void pvalSwitchAddCase( pval *p, pval *Case );
+pval* pvalSwitchWalkCases( pval *p, pval **next_case );
+
+void pvalExtenSetName( pval *p, char *name );
+char *pvalExtenGetName( pval *p );
+void pvalExtenSetRegexten( pval *p );
+void pvalExtenUnSetRegexten( pval *p );
+int pvalExtenGetRegexten( pval *p );
+void pvalExtenSetHints( pval *p, char *hints );
+char* pvalExtenGetHints( pval *p );
+void pvalExtenSetStatement( pval *p, pval *statement );
+pval* pvalExtenGetStatement( pval *p );
+
+void pvalIgnorePatSetPattern( pval *p, char *pat );
+char* pvalIgnorePatGetPattern( pval *p );
+
+void pvalGlobalsAddStatement( pval *p, pval *statement );
+pval* pvalGlobalsWalkStatements( pval *p, pval **next_statement );
+
+void pvalTopLevAddObject( pval *p, pval *contextOrObj );
+pval* pvalTopLevWalkObjects( pval *p, pval **next_obj );
+
+int pvalCheckType( pval *p, char *funcname, pvaltype type );
+
+
+#endif
diff --git a/trunk/include/asterisk/res_odbc.h b/trunk/include/asterisk/res_odbc.h
new file mode 100644
index 000000000..fcb1581e4
--- /dev/null
+++ b/trunk/include/asterisk/res_odbc.h
@@ -0,0 +1,122 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2005, Digium, Inc.
+ * Copyright (C) 2004 - 2005, Anthony Minessale II
+ * Copyright (C) 2006, Tilghman Lesher
+ *
+ * Mark Spencer <markster@digium.com>
+ * Anthony Minessale <anthmct@yahoo.com>
+ * Tilghman Lesher <res_odbc_200603@the-tilghman.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief ODBC resource manager
+ */
+
+#ifndef _ASTERISK_RES_ODBC_H
+#define _ASTERISK_RES_ODBC_H
+
+#include <sql.h>
+#include <sqlext.h>
+#include <sqltypes.h>
+
+typedef enum { ODBC_SUCCESS=0, ODBC_FAIL=-1} odbc_status;
+
+/*! \brief ODBC container */
+struct odbc_obj {
+ ast_mutex_t lock;
+ SQLHDBC con; /* ODBC Connection Handle */
+ struct odbc_class *parent; /* Information about the connection is protected */
+ unsigned int used:1;
+ unsigned int up:1;
+ AST_LIST_ENTRY(odbc_obj) list;
+};
+
+/* functions */
+
+/*!
+ * \brief Executes a prepared statement handle
+ * \param obj The non-NULL result of odbc_request_obj()
+ * \param stmt The prepared statement handle
+ * \retval 0 on success
+ * \retval -1 on failure
+ *
+ * This function was originally designed simply to execute a prepared
+ * statement handle and to retry if the initial execution failed.
+ * Unfortunately, it did this by disconnecting and reconnecting the database
+ * handle which on most databases causes the statement handle to become
+ * invalid. Therefore, this method has been deprecated in favor of
+ * odbc_prepare_and_execute() which allows the statement to be prepared
+ * multiple times, if necessary, in case of a loss of connection.
+ *
+ * This function really only ever worked with MySQL, where the statement handle is
+ * not prepared on the server. If you are not using MySQL, you should avoid it.
+ */
+int ast_odbc_smart_execute(struct odbc_obj *obj, SQLHSTMT stmt); /* DEPRECATED */
+
+/*!
+ * \brief Retrieves a connected ODBC object
+ * \param name The name of the ODBC class for which a connection is needed.
+ * \param check Whether to ensure that a connection is valid before returning the handle. Usually unnecessary.
+ * \retval ODBC object
+ * \retval NULL if there is no connection available with the requested name.
+ *
+ * Connection classes may, in fact, contain multiple connection handles. If
+ * the connection is pooled, then each connection will be dedicated to the
+ * thread which requests it. Note that all connections should be released
+ * when the thread is done by calling odbc_release_obj(), below.
+ */
+struct odbc_obj *ast_odbc_request_obj(const char *name, int check);
+
+/*!
+ * \brief Releases an ODBC object previously allocated by odbc_request_obj()
+ * \param obj The ODBC object
+ */
+void ast_odbc_release_obj(struct odbc_obj *obj);
+
+/*!
+ * \brief Checks an ODBC object to ensure it is still connected
+ * \param obj The ODBC object
+ * \retval 0 if connected
+ * \retval -1 otherwise.
+ */
+int ast_odbc_sanity_check(struct odbc_obj *obj);
+
+/*! \brief Checks if the database natively supports backslash as an escape character.
+ * \param obj The ODBC object
+ * \return Returns 1 if an ESCAPE clause is needed to support '\', 0 otherwise
+ */
+int ast_odbc_backslash_is_escape(struct odbc_obj *obj);
+
+/*! \brief Executes an non prepared statement and returns the resulting
+ * statement handle.
+ * \param obj The ODBC object
+ * \param exec_cb A function callback, which, when called, should return a statement handle with result columns bound.
+ * \param data A parameter to be passed to the exec_cb parameter function, indicating which statement handle is to be prepared.
+ * \retval a statement handle
+ * \retval NULL on error
+ */
+SQLHSTMT ast_odbc_direct_execute(struct odbc_obj *obj, SQLHSTMT (*exec_cb)(struct odbc_obj *obj, void *data), void *data);
+
+/*!
+ * \brief Prepares, executes, and returns the resulting statement handle.
+ * \param obj The ODBC object
+ * \param prepare_cb A function callback, which, when called, should return a statement handle prepared, with any necessary parameters or result columns bound.
+ * \param data A parameter to be passed to the prepare_cb parameter function, indicating which statement handle is to be prepared.
+ * \retval a statement handle
+ * \retval NULL on error
+ */
+SQLHSTMT ast_odbc_prepare_and_execute(struct odbc_obj *obj, SQLHSTMT (*prepare_cb)(struct odbc_obj *obj, void *data), void *data);
+
+#endif /* _ASTERISK_RES_ODBC_H */
diff --git a/trunk/include/asterisk/rtp.h b/trunk/include/asterisk/rtp.h
new file mode 100644
index 000000000..003ff268f
--- /dev/null
+++ b/trunk/include/asterisk/rtp.h
@@ -0,0 +1,293 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2006, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*!
+ * \file rtp.h
+ * \brief Supports RTP and RTCP with Symmetric RTP support for NAT traversal.
+ *
+ * RTP is defined in RFC 3550.
+ */
+
+#ifndef _ASTERISK_RTP_H
+#define _ASTERISK_RTP_H
+
+#include "asterisk/network.h"
+
+#include "asterisk/frame.h"
+#include "asterisk/io.h"
+#include "asterisk/sched.h"
+#include "asterisk/channel.h"
+#include "asterisk/linkedlists.h"
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/* Codes for RTP-specific data - not defined by our AST_FORMAT codes */
+/*! DTMF (RFC2833) */
+#define AST_RTP_DTMF (1 << 0)
+/*! 'Comfort Noise' (RFC3389) */
+#define AST_RTP_CN (1 << 1)
+/*! DTMF (Cisco Proprietary) */
+#define AST_RTP_CISCO_DTMF (1 << 2)
+/*! Maximum RTP-specific code */
+#define AST_RTP_MAX AST_RTP_CISCO_DTMF
+
+/*! Maxmum number of payload defintions for a RTP session */
+#define MAX_RTP_PT 256
+
+#define FLAG_3389_WARNING (1 << 0)
+
+enum ast_rtp_options {
+ AST_RTP_OPT_G726_NONSTANDARD = (1 << 0),
+};
+
+enum ast_rtp_get_result {
+ /*! Failed to find the RTP structure */
+ AST_RTP_GET_FAILED = 0,
+ /*! RTP structure exists but true native bridge can not occur so try partial */
+ AST_RTP_TRY_PARTIAL,
+ /*! RTP structure exists and native bridge can occur */
+ AST_RTP_TRY_NATIVE,
+};
+
+struct ast_rtp;
+
+/*! \brief This is the structure that binds a channel (SIP/Jingle/H.323) to the RTP subsystem
+*/
+struct ast_rtp_protocol {
+ /*! Get RTP struct, or NULL if unwilling to transfer */
+ enum ast_rtp_get_result (* const get_rtp_info)(struct ast_channel *chan, struct ast_rtp **rtp);
+ /*! Get RTP struct, or NULL if unwilling to transfer */
+ enum ast_rtp_get_result (* const get_vrtp_info)(struct ast_channel *chan, struct ast_rtp **rtp);
+ /*! Get RTP struct, or NULL if unwilling to transfer */
+ enum ast_rtp_get_result (* const get_trtp_info)(struct ast_channel *chan, struct ast_rtp **rtp);
+ /*! Set RTP peer */
+ int (* const set_rtp_peer)(struct ast_channel *chan, struct ast_rtp *peer, struct ast_rtp *vpeer, struct ast_rtp *tpeer, int codecs, int nat_active);
+ int (* const get_codec)(struct ast_channel *chan);
+ const char * const type;
+ AST_LIST_ENTRY(ast_rtp_protocol) list;
+};
+
+/*! \brief RTCP quality report storage */
+struct ast_rtp_quality {
+ unsigned int local_ssrc; /*!< Our SSRC */
+ unsigned int local_lostpackets; /*!< Our lost packets */
+ double local_jitter; /*!< Our calculated jitter */
+ unsigned int local_count; /*!< Number of received packets */
+ unsigned int remote_ssrc; /*!< Their SSRC */
+ unsigned int remote_lostpackets; /*!< Their lost packets */
+ double remote_jitter; /*!< Their reported jitter */
+ unsigned int remote_count; /*!< Number of transmitted packets */
+ double rtt; /*!< Round trip time */
+};
+
+/*! RTP callback structure */
+typedef int (*ast_rtp_callback)(struct ast_rtp *rtp, struct ast_frame *f, void *data);
+
+/*!
+ * \brief Get the amount of space required to hold an RTP session
+ * \return number of bytes required
+ */
+size_t ast_rtp_alloc_size(void);
+
+/*!
+ * \brief Initializate a RTP session.
+ *
+ * \param sched
+ * \param io
+ * \param rtcpenable
+ * \param callbackmode
+ * \returns A representation (structure) of an RTP session.
+ */
+struct ast_rtp *ast_rtp_new(struct sched_context *sched, struct io_context *io, int rtcpenable, int callbackmode);
+
+/*!
+ * \brief Initializate a RTP session using an in_addr structure.
+ *
+ * This fuction gets called by ast_rtp_new().
+ *
+ * \param sched
+ * \param io
+ * \param rtcpenable
+ * \param callbackmode
+ * \param in
+ * \returns A representation (structure) of an RTP session.
+ */
+struct ast_rtp *ast_rtp_new_with_bindaddr(struct sched_context *sched, struct io_context *io, int rtcpenable, int callbackmode, struct in_addr in);
+
+void ast_rtp_set_peer(struct ast_rtp *rtp, struct sockaddr_in *them);
+
+/* Copies from rtp to them and returns 1 if there was a change or 0 if it was already the same */
+int ast_rtp_get_peer(struct ast_rtp *rtp, struct sockaddr_in *them);
+
+void ast_rtp_get_us(struct ast_rtp *rtp, struct sockaddr_in *us);
+
+struct ast_rtp *ast_rtp_get_bridged(struct ast_rtp *rtp);
+
+/*! Destroy RTP session */
+void ast_rtp_destroy(struct ast_rtp *rtp);
+
+void ast_rtp_reset(struct ast_rtp *rtp);
+
+/*! Stop RTP session, do not destroy structure */
+void ast_rtp_stop(struct ast_rtp *rtp);
+
+void ast_rtp_set_callback(struct ast_rtp *rtp, ast_rtp_callback callback);
+
+void ast_rtp_set_data(struct ast_rtp *rtp, void *data);
+
+int ast_rtp_write(struct ast_rtp *rtp, struct ast_frame *f);
+
+struct ast_frame *ast_rtp_read(struct ast_rtp *rtp);
+
+struct ast_frame *ast_rtcp_read(struct ast_rtp *rtp);
+
+int ast_rtp_fd(struct ast_rtp *rtp);
+
+int ast_rtcp_fd(struct ast_rtp *rtp);
+
+int ast_rtp_senddigit_begin(struct ast_rtp *rtp, char digit);
+
+int ast_rtp_senddigit_end(struct ast_rtp *rtp, char digit);
+
+int ast_rtp_sendcng(struct ast_rtp *rtp, int level);
+
+int ast_rtp_setqos(struct ast_rtp *rtp, int tos, int cos, char *desc);
+
+/*! \brief Setting RTP payload types from lines in a SDP description: */
+void ast_rtp_pt_clear(struct ast_rtp* rtp);
+/*! \brief Set payload types to defaults */
+void ast_rtp_pt_default(struct ast_rtp* rtp);
+
+/*! \brief Copy payload types between RTP structures */
+void ast_rtp_pt_copy(struct ast_rtp *dest, struct ast_rtp *src);
+
+/*! \brief Activate payload type */
+void ast_rtp_set_m_type(struct ast_rtp* rtp, int pt);
+
+/*! \brief clear payload type */
+void ast_rtp_unset_m_type(struct ast_rtp* rtp, int pt);
+
+/*! \brief Initiate payload type to a known MIME media type for a codec */
+int ast_rtp_set_rtpmap_type(struct ast_rtp* rtp, int pt,
+ char *mimeType, char *mimeSubtype,
+ enum ast_rtp_options options);
+
+/*! \brief Mapping between RTP payload format codes and Asterisk codes: */
+struct rtpPayloadType ast_rtp_lookup_pt(struct ast_rtp* rtp, int pt);
+int ast_rtp_lookup_code(struct ast_rtp* rtp, int isAstFormat, int code);
+
+void ast_rtp_get_current_formats(struct ast_rtp* rtp,
+ int* astFormats, int* nonAstFormats);
+
+/*! \brief Mapping an Asterisk code into a MIME subtype (string): */
+const char *ast_rtp_lookup_mime_subtype(int isAstFormat, int code,
+ enum ast_rtp_options options);
+
+/*! \brief Build a string of MIME subtype names from a capability list */
+char *ast_rtp_lookup_mime_multiple(char *buf, size_t size, const int capability,
+ const int isAstFormat, enum ast_rtp_options options);
+
+void ast_rtp_setnat(struct ast_rtp *rtp, int nat);
+
+int ast_rtp_getnat(struct ast_rtp *rtp);
+
+/*! \brief Indicate whether this RTP session is carrying DTMF or not */
+void ast_rtp_setdtmf(struct ast_rtp *rtp, int dtmf);
+
+/*! \brief Compensate for devices that send RFC2833 packets all at once */
+void ast_rtp_setdtmfcompensate(struct ast_rtp *rtp, int compensate);
+
+/*! \brief Enable STUN capability */
+void ast_rtp_setstun(struct ast_rtp *rtp, int stun_enable);
+
+/*! \brief Generic STUN request
+ * send a generic stun request to the server specified.
+ * \param s the socket used to send the request
+ * \param dst the address of the STUN server
+ * \param username if non null, add the username in the request
+ * \param answer if non null, the function waits for a response and
+ * puts here the externally visible address.
+ * \return 0 on success, other values on error.
+ * The interface it may change in the future.
+ */
+int ast_stun_request(int s, struct sockaddr_in *dst,
+ const char *username, struct sockaddr_in *answer);
+
+/*! \brief Send STUN request for an RTP socket
+ * Deprecated, this is just a wrapper for ast_rtp_stun_request()
+ */
+void ast_rtp_stun_request(struct ast_rtp *rtp, struct sockaddr_in *suggestion, const char *username);
+
+/*! \brief The RTP bridge.
+ \arg \ref AstRTPbridge
+*/
+int ast_rtp_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms);
+
+/*! \brief Register an RTP channel client */
+int ast_rtp_proto_register(struct ast_rtp_protocol *proto);
+
+/*! \brief Unregister an RTP channel client */
+void ast_rtp_proto_unregister(struct ast_rtp_protocol *proto);
+
+int ast_rtp_make_compatible(struct ast_channel *dest, struct ast_channel *src, int media);
+
+/*! \brief If possible, create an early bridge directly between the devices without
+ having to send a re-invite later */
+int ast_rtp_early_bridge(struct ast_channel *c0, struct ast_channel *c1);
+
+/*! \brief Return RTCP quality string */
+char *ast_rtp_get_quality(struct ast_rtp *rtp, struct ast_rtp_quality *qual);
+
+/*! \brief Send an H.261 fast update request. Some devices need this rather than the XML message in SIP */
+int ast_rtcp_send_h261fur(void *data);
+
+void ast_rtp_init(void); /*! Initialize RTP subsystem */
+int ast_rtp_reload(void); /*! reload rtp configuration */
+void ast_rtp_new_init(struct ast_rtp *rtp);
+
+/*! Set codec preference */
+int ast_rtp_codec_setpref(struct ast_rtp *rtp, struct ast_codec_pref *prefs);
+
+/*! Get codec preference */
+struct ast_codec_pref *ast_rtp_codec_getpref(struct ast_rtp *rtp);
+
+/*! get format from predefined dynamic payload format */
+int ast_rtp_codec_getformat(int pt);
+
+/*! \brief Set rtp timeout */
+void ast_rtp_set_rtptimeout(struct ast_rtp *rtp, int timeout);
+/*! \brief Set rtp hold timeout */
+void ast_rtp_set_rtpholdtimeout(struct ast_rtp *rtp, int timeout);
+/*! \brief set RTP keepalive interval */
+void ast_rtp_set_rtpkeepalive(struct ast_rtp *rtp, int period);
+/*! \brief Get RTP keepalive interval */
+int ast_rtp_get_rtpkeepalive(struct ast_rtp *rtp);
+/*! \brief Get rtp hold timeout */
+int ast_rtp_get_rtpholdtimeout(struct ast_rtp *rtp);
+/*! \brief Get rtp timeout */
+int ast_rtp_get_rtptimeout(struct ast_rtp *rtp);
+/* \brief Put RTP timeout timers on hold during another transaction, like T.38 */
+void ast_rtp_set_rtptimers_onhold(struct ast_rtp *rtp);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _ASTERISK_RTP_H */
diff --git a/trunk/include/asterisk/say.h b/trunk/include/asterisk/say.h
new file mode 100644
index 000000000..37098402c
--- /dev/null
+++ b/trunk/include/asterisk/say.h
@@ -0,0 +1,170 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2005, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief Say numbers and dates (maybe words one day too)
+ */
+
+#ifndef _ASTERISK_SAY_H
+#define _ASTERISK_SAY_H
+
+#include "asterisk/channel.h"
+#include "asterisk/file.h"
+
+#include <time.h>
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/*! \brief
+ * The basic ast_say_* functions are implemented as function pointers,
+ * initialized to the function say_stub() which simply returns an error.
+ * Other interfaces, declared here as regular functions, are simply
+ * wrappers around the basic functions.
+ *
+ * An implementation of the basic ast_say functions (e.g. from say.c or from
+ * a dynamically loaded module) will just have to reassign the pointers
+ * to the relevant functions to override the previous implementation.
+ *
+ * \todo XXX
+ * As the conversion from the old implementation of say.c to the new
+ * implementation will be completed, and the API suitably reworked by
+ * removing redundant functions and/or arguments, this mechanism may be
+ * reverted back to pure static functions, if needed.
+ */
+#if defined(SAY_STUBS)
+/* provide declarations for the *say*() functions
+ * and initialize them to the stub function
+ */
+static int say_stub(struct ast_channel *chan, ...)
+{
+ ast_log(LOG_WARNING, "no implementation for the say() functions\n");
+ return -1;
+};
+
+#undef SAY_STUBS
+#define SAY_INIT(x) = (typeof (x))say_stub
+#define SAY_EXTERN
+#else
+#define SAY_INIT(x)
+#define SAY_EXTERN extern
+#endif
+
+/*
+ * \brief says a number
+ * \param chan channel to say them number on
+ * \param num number to say on the channel
+ * \param ints which dtmf to interrupt on
+ * \param lang language to speak the number
+ * \param options set to 'f' for female, 'm' for male, 'c' for commune, 'n' for neuter, 'p' for plural
+ * Vocally says a number on a given channel
+ * \retval 0 on success
+ * \retval DTMF digit on interrupt
+ * \retval -1 on failure
+ */
+int ast_say_number(struct ast_channel *chan, int num,
+ const char *ints, const char *lang, const char *options);
+
+/* Same as above with audiofd for received audio and returns 1 on ctrlfd being readable */
+SAY_EXTERN int (* ast_say_number_full)(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options, int audiofd, int ctrlfd) SAY_INIT(ast_say_number_full);
+
+/*
+ * \brief says an enumeration
+ * \param chan channel to say them enumeration on
+ * \param num number to say on the channel
+ * \param ints which dtmf to interrupt on
+ * \param lang language to speak the enumeration
+ * \param options set to 'f' for female, 'm' for male, 'c' for commune, 'n' for neuter, 'p' for plural
+ * Vocally says a enumeration on a given channel (first, sencond, third, forth, thirtyfirst, hundredth, ....)
+ * especially useful for dates and messages. says 'last' if num equals to INT_MAX
+ * \retval 0 on success
+ * \retval DTMF digit on interrupt
+ * \retval -1 on failure
+ */
+int ast_say_enumeration(struct ast_channel *chan, int num,
+ const char *ints, const char *lang, const char *options);
+
+SAY_EXTERN int (* ast_say_enumeration_full)(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options, int audiofd, int ctrlfd) SAY_INIT(ast_say_enumeration_full);
+
+/*
+ * \brief says digits
+ * \param chan channel to act upon
+ * \param num number to speak
+ * \param ints which dtmf to interrupt on
+ * \param lang language to speak
+ * Vocally says digits of a given number
+ * \retval 0 on success
+ * \retval DTMF if interrupted
+ * \retval -1 on failure
+ */
+int ast_say_digits(struct ast_channel *chan, int num,
+ const char *ints, const char *lang);
+
+int ast_say_digits_full(struct ast_channel *chan, int num,
+ const char *ints, const char *lang, int audiofd, int ctrlfd);
+
+/*
+ * \brief says digits of a string
+ * \param chan channel to act upon
+ * \param num string to speak
+ * \param ints which dtmf to interrupt on
+ * \param lang language to speak in
+ * Vocally says the digits of a given string
+ * \retval 0 on succes
+ * \retval DTMF if interrupted
+ * \retval -1 on failure
+ */
+int ast_say_digit_str(struct ast_channel *chan, const char *num,
+ const char *ints, const char *lang);
+
+SAY_EXTERN int (* ast_say_digit_str_full)(struct ast_channel *chan, const char *num, const char *ints, const char *lang, int audiofd, int ctrlfd) SAY_INIT(ast_say_digit_str_full);
+
+/*
+ * the generic 'say' routine, with the first chars in the string
+ * defining the format to use
+ */
+SAY_EXTERN int (* ast_say_full)(struct ast_channel *chan, const char *num, const char *ints, const char *lang, const char *options, int audiofd, int ctrlfd) SAY_INIT(ast_say_full);
+
+/*
+ * other function to pronounce character and phonetic strings
+ */
+int ast_say_character_str(struct ast_channel *chan, const char *num,
+ const char *ints, const char *lang);
+
+SAY_EXTERN int (* ast_say_character_str_full)(struct ast_channel *chan, const char *num, const char *ints, const char *lang, int audiofd, int ctrlfd) SAY_INIT(ast_say_character_str_full);
+
+int ast_say_phonetic_str(struct ast_channel *chan, const char *num,
+ const char *ints, const char *lang);
+
+SAY_EXTERN int (* ast_say_phonetic_str_full)(struct ast_channel *chan, const char *num, const char *ints, const char *lang, int audiofd, int ctrlfd) SAY_INIT(ast_say_phonetic_str_full);
+
+SAY_EXTERN int (* ast_say_datetime)(struct ast_channel *chan, time_t t, const char *ints, const char *lang) SAY_INIT(ast_say_datetime);
+SAY_EXTERN int (* ast_say_time)(struct ast_channel *chan, time_t t, const char *ints, const char *lang) SAY_INIT(ast_say_time);
+
+SAY_EXTERN int (* ast_say_date)(struct ast_channel *chan, time_t t, const char *ints, const char *lang) SAY_INIT(ast_say_date);
+
+SAY_EXTERN int (* ast_say_datetime_from_now)(struct ast_channel *chan, time_t t, const char *ints, const char *lang) SAY_INIT(ast_say_datetime_from_now);
+
+SAY_EXTERN int (* ast_say_date_with_format)(struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *timezone) SAY_INIT(ast_say_date_with_format);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _ASTERISK_SAY_H */
diff --git a/trunk/include/asterisk/sched.h b/trunk/include/asterisk/sched.h
new file mode 100644
index 000000000..f074518c5
--- /dev/null
+++ b/trunk/include/asterisk/sched.h
@@ -0,0 +1,176 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2005, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief Scheduler Routines (derived from cheops)
+ */
+
+#ifndef _ASTERISK_SCHED_H
+#define _ASTERISK_SCHED_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/*! \brief Max num of schedule structs
+ * \note The max number of schedule structs to keep around
+ * for use. Undefine to disable schedule structure
+ * caching. (Only disable this on very low memory
+ * machines)
+ */
+#define SCHED_MAX_CACHE 128
+
+struct sched_context;
+
+/*! \brief New schedule context
+ * \note Create a scheduling context
+ * \return Returns a malloc'd sched_context structure, NULL on failure
+ */
+struct sched_context *sched_context_create(void);
+
+/*! \brief destroys a schedule context
+ * Destroys (free's) the given sched_context structure
+ * \param c Context to free
+ * \return Returns 0 on success, -1 on failure
+ */
+void sched_context_destroy(struct sched_context *c);
+
+/*! \brief callback for a cheops scheduler
+ * A cheops scheduler callback takes a pointer with callback data and
+ * \return returns a 0 if it should not be run again, or non-zero if it should be
+ * rescheduled to run again
+ */
+typedef int (*ast_sched_cb)(const void *data);
+#define AST_SCHED_CB(a) ((ast_sched_cb)(a))
+
+/*! \brief Adds a scheduled event
+ * Schedule an event to take place at some point in the future. callback
+ * will be called with data as the argument, when milliseconds into the
+ * future (approximately)
+ * If callback returns 0, no further events will be re-scheduled
+ * \param con Scheduler context to add
+ * \param when how many milliseconds to wait for event to occur
+ * \param callback function to call when the amount of time expires
+ * \param data data to pass to the callback
+ * \return Returns a schedule item ID on success, -1 on failure
+ */
+int ast_sched_add(struct sched_context *con, int when, ast_sched_cb callback, const void *data);
+
+/*!
+ * \brief replace a scheduler entry
+ *
+ * This deletes the scheduler entry for old_id if it exists, and then
+ * calls ast_sched_add to create a new entry. A negative old_id will
+ * be ignored.
+ *
+ * \retval -1 failure
+ * \retval otherwise, returns scheduled item ID
+ */
+int ast_sched_replace(int old_id, struct sched_context *con, int when, ast_sched_cb callback, const void *data);
+
+/*!Adds a scheduled event with rescheduling support
+ * \param con Scheduler context to add
+ * \param when how many milliseconds to wait for event to occur
+ * \param callback function to call when the amount of time expires
+ * \param data data to pass to the callback
+ * \param variable If true, the result value of callback function will be
+ * used for rescheduling
+ * Schedule an event to take place at some point in the future. Callback
+ * will be called with data as the argument, when milliseconds into the
+ * future (approximately)
+ * If callback returns 0, no further events will be re-scheduled
+ * \return Returns a schedule item ID on success, -1 on failure
+ */
+int ast_sched_add_variable(struct sched_context *con, int when, ast_sched_cb callback, const void *data, int variable);
+
+/*!
+ * \brief replace a scheduler entry
+ *
+ * This deletes the scheduler entry for old_id if it exists, and then
+ * calls ast_sched_add to create a new entry. A negative old_id will
+ * be ignored.
+ *
+ * \retval -1 failure
+ * \retval otherwise, returns scheduled item ID
+ */
+int ast_sched_replace_variable(int old_id, struct sched_context *con, int when, ast_sched_cb callback, const void *data, int variable);
+
+/*! \brief Deletes a scheduled event
+ * Remove this event from being run. A procedure should not remove its
+ * own event, but return 0 instead.
+ * \param con scheduling context to delete item from
+ * \param id ID of the scheduled item to delete
+ * \return Returns 0 on success, -1 on failure
+ */
+int ast_sched_del(struct sched_context *con, int id);
+
+/*! \brief Determines number of seconds until the next outstanding event to take place
+ * Determine the number of seconds until the next outstanding event
+ * should take place, and return the number of milliseconds until
+ * it needs to be run. This value is perfect for passing to the poll
+ * call.
+ * \param con context to act upon
+ * \return Returns "-1" if there is nothing there are no scheduled events
+ * (and thus the poll should not timeout)
+ */
+int ast_sched_wait(struct sched_context *con);
+
+/*! \brief Runs the queue
+ * \param con Scheduling context to run
+ * Run the queue, executing all callbacks which need to be performed
+ * at this time.
+ * \param con context to act upon
+ * \return Returns the number of events processed.
+ */
+int ast_sched_runq(struct sched_context *con);
+
+/*! \brief Dumps the scheduler contents
+ * Debugging: Dump the contents of the scheduler to stderr
+ * \param con Context to dump
+ */
+void ast_sched_dump(const struct sched_context *con);
+
+/*! \brief Returns the number of seconds before an event takes place
+ * \param con Context to use
+ * \param id Id to dump
+ */
+long ast_sched_when(struct sched_context *con,int id);
+
+/*!
+ * \brief Convenience macro for objects and reference (add)
+ *
+ */
+#define ast_sched_add_object(obj,con,when,callback) ast_sched_add((con),(when),(callback), ASTOBJ_REF((obj)))
+
+/*!
+ * \brief Convenience macro for objects and reference (del)
+ *
+ */
+#define ast_sched_del_object(obj,destructor,con,id) do { \
+ if ((id) > -1) { \
+ ast_sched_del((con),(id)); \
+ (id) = -1; \
+ ASTOBJ_UNREF((obj),(destructor)); \
+ } \
+} while(0)
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _ASTERISK_SCHED_H */
diff --git a/trunk/include/asterisk/sha1.h b/trunk/include/asterisk/sha1.h
new file mode 100644
index 000000000..d530c3206
--- /dev/null
+++ b/trunk/include/asterisk/sha1.h
@@ -0,0 +1,73 @@
+/*
+ * sha1.h
+ *
+ * Description:
+ * This is the header file for code which implements the Secure
+ * Hashing Algorithm 1 as defined in FIPS PUB 180-1 published
+ * April 17, 1995.
+ *
+ * Many of the variable names in this code, especially the
+ * single character names, were used because those were the names
+ * used in the publication.
+ *
+ * Please read the file sha1.c for more information.
+ *
+ */
+
+
+#ifndef _SHA1_H_
+#define _SHA1_H_
+
+/*
+ * We assume that the standard asterisk headers have been included before this one.
+ * If you do not have the ISO standard stdint.h header file, then you
+ * must typdef the following:
+ * name meaning
+ * uint32_t unsigned 32 bit integer
+ * uint8_t unsigned 8 bit integer (i.e., unsigned char)
+ *
+ */
+
+#ifndef _SHA_enum_
+#define _SHA_enum_
+enum
+{
+ shaSuccess = 0,
+ shaNull, /* Null pointer parameter */
+ shaInputTooLong, /* input data too long */
+ shaStateError /* called Input after Result */
+};
+#endif
+#define SHA1HashSize 20
+
+/*!
+ * \brief This structure will hold context information for the SHA-1 hashing operation
+*/
+typedef struct SHA1Context
+{
+ uint32_t Intermediate_Hash[SHA1HashSize/4]; /*! Message Digest */
+
+ uint32_t Length_Low; /*!< Message length in bits */
+ uint32_t Length_High; /*!< Message length in bits */
+
+ /* Index into message block array */
+ uint32_t Message_Block_Index; /*!< 8 bits actually suffice */
+ uint8_t Message_Block[64]; /*!< 512-bit message blocks */
+
+ int Computed; /*!< Is the digest computed? */
+ int Corrupted; /*!< Is the message digest corrupted? */
+} SHA1Context;
+
+/*
+ * Function Prototypes
+ */
+
+
+int SHA1Reset( SHA1Context *);
+int SHA1Input( SHA1Context *,
+ const uint8_t *,
+ unsigned int);
+int SHA1Result( SHA1Context *,
+ uint8_t Message_Digest[SHA1HashSize]);
+
+#endif
diff --git a/trunk/include/asterisk/slinfactory.h b/trunk/include/asterisk/slinfactory.h
new file mode 100644
index 000000000..603c648c7
--- /dev/null
+++ b/trunk/include/asterisk/slinfactory.h
@@ -0,0 +1,65 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2005, Anthony Minessale II
+ *
+ * Anthony Minessale <anthmct@yahoo.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief A machine to gather up arbitrary frames and convert them
+ * to raw slinear on demand.
+ */
+
+#ifndef _ASTERISK_SLINFACTORY_H
+#define _ASTERISK_SLINFACTORY_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+struct ast_slinfactory {
+ AST_LIST_HEAD_NOLOCK(, ast_frame) queue;
+ struct ast_trans_pvt *trans;
+ short hold[1280];
+ short *offset;
+ size_t holdlen; /*!< in samples */
+ unsigned int size; /*!< in samples */
+ unsigned int format;
+};
+
+void ast_slinfactory_init(struct ast_slinfactory *sf);
+
+/*!
+ * \brief Destroy the contents of a slinfactory
+ *
+ * \arg sf the slinfactory that is no longer needed
+ *
+ * This function will free any memory allocated for the contents of the
+ * slinfactory. It does not free the slinfactory itself. If the sf is
+ * malloc'd, then it must be explicitly free'd after calling this function.
+ *
+ * \return nothing
+ */
+void ast_slinfactory_destroy(struct ast_slinfactory *sf);
+
+int ast_slinfactory_feed(struct ast_slinfactory *sf, struct ast_frame *f);
+int ast_slinfactory_read(struct ast_slinfactory *sf, short *buf, size_t samples);
+unsigned int ast_slinfactory_available(const struct ast_slinfactory *sf);
+void ast_slinfactory_flush(struct ast_slinfactory *sf);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _ASTERISK_SLINFACTORY_H */
diff --git a/trunk/include/asterisk/smdi.h b/trunk/include/asterisk/smdi.h
new file mode 100644
index 000000000..6260d9d2d
--- /dev/null
+++ b/trunk/include/asterisk/smdi.h
@@ -0,0 +1,127 @@
+/*
+ * Asterisk -- A telephony toolkit for Linux.
+ *
+ * Copyright (C) 2005-2006, Digium, Inc.
+ *
+ * Matthew A. Nicholson <mnicholson@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*!
+ * \file
+ * \brief SMDI support for Asterisk.
+ * \author Matthew A. Nicholson <mnicholson@digium.com>
+ */
+
+
+/* C is simply a ego booster for those who want to do objects the hard way. */
+
+
+#ifndef ASTERISK_SMDI_H
+#define ASTERISK_SMDI_H
+
+#include <termios.h>
+#include <time.h>
+
+#include "asterisk/config.h"
+#include "asterisk/module.h"
+#include "asterisk/astobj.h"
+
+#define SMDI_MESG_DESK_NUM_LEN 3
+#define SMDI_MESG_DESK_TERM_LEN 4
+#define SMDI_MWI_FAIL_CAUSE_LEN 3
+#define SMDI_MAX_STATION_NUM_LEN 10
+#define SMDI_MAX_FILENAME_LEN 256
+
+/*!
+ * \brief An SMDI message waiting indicator message.
+ *
+ * The ast_smdi_mwi_message structure contains the parsed out parts of an smdi
+ * message. Each ast_smdi_interface structure has a message queue consisting
+ * ast_smdi_mwi_message structures.
+ */
+struct ast_smdi_mwi_message {
+ ASTOBJ_COMPONENTS(struct ast_smdi_mwi_message);
+ char fwd_st[SMDI_MAX_STATION_NUM_LEN + 1]; /* forwarding station number */
+ char cause[SMDI_MWI_FAIL_CAUSE_LEN + 1]; /* the type of failure */
+ struct timeval timestamp; /* a timestamp for the message */
+};
+
+/*!
+ * \brief An SMDI message desk message.
+ *
+ * The ast_smdi_md_message structure contains the parsed out parts of an smdi
+ * message. Each ast_smdi_interface structure has a message queue consisting
+ * ast_smdi_md_message structures.
+ */
+struct ast_smdi_md_message {
+ ASTOBJ_COMPONENTS(struct ast_smdi_md_message);
+ char mesg_desk_num[SMDI_MESG_DESK_NUM_LEN + 1]; /* message desk number */
+ char mesg_desk_term[SMDI_MESG_DESK_TERM_LEN + 1]; /* message desk terminal */
+ char fwd_st[SMDI_MAX_STATION_NUM_LEN + 1]; /* forwarding station number */
+ char calling_st[SMDI_MAX_STATION_NUM_LEN + 1]; /* calling station number */
+ char type; /* the type of the call */
+ struct timeval timestamp; /* a timestamp for the message */
+};
+
+/*! \brief SMDI message desk message queue. */
+struct ast_smdi_md_queue {
+ ASTOBJ_CONTAINER_COMPONENTS(struct ast_smdi_md_message);
+};
+
+/*! \brief SMDI message waiting indicator message queue. */
+struct ast_smdi_mwi_queue {
+ ASTOBJ_CONTAINER_COMPONENTS(struct ast_smdi_mwi_message);
+};
+
+/*!
+ * \brief SMDI interface structure.
+ *
+ * The ast_smdi_interface structure holds information on a serial port that
+ * should be monitored for SMDI activity. The structure contains a message
+ * queue of messages that have been received on the interface.
+ */
+struct ast_smdi_interface {
+ ASTOBJ_COMPONENTS_FULL(struct ast_smdi_interface, SMDI_MAX_FILENAME_LEN, 1);
+ struct ast_smdi_md_queue md_q;
+ struct ast_smdi_mwi_queue mwi_q;
+ FILE *file;
+ int fd;
+ pthread_t thread;
+ struct termios mode;
+ int msdstrip;
+ long msg_expiry;
+};
+
+
+/* MD message queue functions */
+struct ast_smdi_md_message *ast_smdi_md_message_pop(struct ast_smdi_interface *iface);
+struct ast_smdi_md_message *ast_smdi_md_message_wait(struct ast_smdi_interface *iface, int timeout);
+void ast_smdi_md_message_putback(struct ast_smdi_interface *iface, struct ast_smdi_md_message *msg);
+
+/* MWI message queue functions */
+struct ast_smdi_mwi_message *ast_smdi_mwi_message_pop(struct ast_smdi_interface *iface);
+struct ast_smdi_mwi_message *ast_smdi_mwi_message_wait(struct ast_smdi_interface *iface, int timeout);
+void ast_smdi_mwi_message_putback(struct ast_smdi_interface *iface, struct ast_smdi_mwi_message *msg);
+
+struct ast_smdi_interface *ast_smdi_interface_find(const char *iface_name);
+
+/* MWI functions */
+int ast_smdi_mwi_set(struct ast_smdi_interface *iface, const char *mailbox);
+int ast_smdi_mwi_unset(struct ast_smdi_interface *iface, const char *mailbox);
+
+void ast_smdi_md_message_destroy(struct ast_smdi_md_message *msg);
+void ast_smdi_mwi_message_destroy(struct ast_smdi_mwi_message *msg);
+
+void ast_smdi_interface_destroy(struct ast_smdi_interface *iface);
+
+#endif /* !ASTERISK_SMDI_H */
diff --git a/trunk/include/asterisk/speech.h b/trunk/include/asterisk/speech.h
new file mode 100644
index 000000000..54e9c69ac
--- /dev/null
+++ b/trunk/include/asterisk/speech.h
@@ -0,0 +1,156 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2006, Digium, Inc.
+ *
+ * Joshua Colp <jcolp@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief Generic Speech Recognition API
+ */
+
+#ifndef _ASTERISK_SPEECH_H
+#define _ASTERISK_SPEECH_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/* Speech structure flags */
+enum ast_speech_flags {
+ AST_SPEECH_QUIET = (1 << 0), /* Quiet down output... they are talking */
+ AST_SPEECH_SPOKE = (1 << 1), /* Speaker spoke! */
+ AST_SPEECH_HAVE_RESULTS = (1 << 2), /* Results are present */
+};
+
+/* Speech structure states - in order of expected change */
+enum ast_speech_states {
+ AST_SPEECH_STATE_NOT_READY = 0, /* Not ready to accept audio */
+ AST_SPEECH_STATE_READY, /* Accepting audio */
+ AST_SPEECH_STATE_WAIT, /* Wait for results to become available */
+ AST_SPEECH_STATE_DONE, /* Processing is all done */
+};
+
+enum ast_speech_results_type {
+ AST_SPEECH_RESULTS_TYPE_NORMAL = 0,
+ AST_SPEECH_RESULTS_TYPE_NBEST,
+};
+
+/* Speech structure */
+struct ast_speech {
+ /*! Structure lock */
+ ast_mutex_t lock;
+ /*! Set flags */
+ unsigned int flags;
+ /*! Processing sound (used when engine is processing audio and getting results) */
+ char *processing_sound;
+ /*! Current state of structure */
+ int state;
+ /*! Expected write format */
+ int format;
+ /*! Data for speech engine */
+ void *data;
+ /*! Cached results */
+ struct ast_speech_result *results;
+ /*! Type of results we want */
+ enum ast_speech_results_type results_type;
+ /*! Pointer to the engine used by this speech structure */
+ struct ast_speech_engine *engine;
+};
+
+/* Speech recognition engine structure */
+struct ast_speech_engine {
+ /*! Name of speech engine */
+ char *name;
+ /*! Set up the speech structure within the engine */
+ int (*create)(struct ast_speech *speech, int format);
+ /*! Destroy any data set on the speech structure by the engine */
+ int (*destroy)(struct ast_speech *speech);
+ /*! Load a local grammar on the speech structure */
+ int (*load)(struct ast_speech *speech, char *grammar_name, char *grammar);
+ /*! Unload a local grammar */
+ int (*unload)(struct ast_speech *speech, char *grammar_name);
+ /*! Activate a loaded grammar */
+ int (*activate)(struct ast_speech *speech, char *grammar_name);
+ /*! Deactivate a loaded grammar */
+ int (*deactivate)(struct ast_speech *speech, char *grammar_name);
+ /*! Write audio to the speech engine */
+ int (*write)(struct ast_speech *speech, void *data, int len);
+ /*! Signal DTMF was received */
+ int (*dtmf)(struct ast_speech *speech, const char *dtmf);
+ /*! Prepare engine to accept audio */
+ int (*start)(struct ast_speech *speech);
+ /*! Change an engine specific setting */
+ int (*change)(struct ast_speech *speech, char *name, const char *value);
+ /*! Change the type of results we want back */
+ int (*change_results_type)(struct ast_speech *speech, enum ast_speech_results_type results_type);
+ /*! Try to get results */
+ struct ast_speech_result *(*get)(struct ast_speech *speech);
+ /*! Accepted formats by the engine */
+ int formats;
+ AST_LIST_ENTRY(ast_speech_engine) list;
+};
+
+/* Result structure */
+struct ast_speech_result {
+ /*! Recognized text */
+ char *text;
+ /*! Result score */
+ int score;
+ /*! NBest Alternative number if in NBest results type */
+ int nbest_num;
+ /*! Matched grammar */
+ char *grammar;
+ /*! List information */
+ AST_LIST_ENTRY(ast_speech_result) list;
+};
+
+/*! \brief Activate a grammar on a speech structure */
+int ast_speech_grammar_activate(struct ast_speech *speech, char *grammar_name);
+/*! \brief Deactivate a grammar on a speech structure */
+int ast_speech_grammar_deactivate(struct ast_speech *speech, char *grammar_name);
+/*! \brief Load a grammar on a speech structure (not globally) */
+int ast_speech_grammar_load(struct ast_speech *speech, char *grammar_name, char *grammar);
+/*! \brief Unload a grammar */
+int ast_speech_grammar_unload(struct ast_speech *speech, char *grammar_name);
+/*! \brief Get speech recognition results */
+struct ast_speech_result *ast_speech_results_get(struct ast_speech *speech);
+/*! \brief Free a set of results */
+int ast_speech_results_free(struct ast_speech_result *result);
+/*! \brief Indicate to the speech engine that audio is now going to start being written */
+void ast_speech_start(struct ast_speech *speech);
+/*! \brief Create a new speech structure */
+struct ast_speech *ast_speech_new(char *engine_name, int formats);
+/*! \brief Destroy a speech structure */
+int ast_speech_destroy(struct ast_speech *speech);
+/*! \brief Write audio to the speech engine */
+int ast_speech_write(struct ast_speech *speech, void *data, int len);
+/*! \brief Signal to the engine that DTMF was received */
+int ast_speech_dtmf(struct ast_speech *speech, const char *dtmf);
+/*! \brief Change an engine specific attribute */
+int ast_speech_change(struct ast_speech *speech, char *name, const char *value);
+/*! \brief Change the type of results we want */
+int ast_speech_change_results_type(struct ast_speech *speech, enum ast_speech_results_type results_type);
+/*! \brief Change state of a speech structure */
+int ast_speech_change_state(struct ast_speech *speech, int state);
+/*! \brief Register a speech recognition engine */
+int ast_speech_register(struct ast_speech_engine *engine);
+/*! \brief Unregister a speech recognition engine */
+int ast_speech_unregister(char *engine_name);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _ASTERISK_SPEECH_H */
diff --git a/trunk/include/asterisk/srv.h b/trunk/include/asterisk/srv.h
new file mode 100644
index 000000000..567b40844
--- /dev/null
+++ b/trunk/include/asterisk/srv.h
@@ -0,0 +1,45 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2005, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*
+ * DNS SRV record support
+ */
+
+#ifndef _ASTERISK_SRV_H
+#define _ASTERISK_SRV_H
+
+/*!
+ \file srv.h
+ \brief Support for DNS SRV records, used in to locate SIP services.
+ \note Note: This SRV record support will respect the priority and
+ weight elements of the records that are returned, but there are
+ no provisions for retrying or failover between records.
+*/
+
+/*! Lookup entry in SRV records Returns 1 if found, 0 if not found, -1 on hangup
+ Only do SRV record lookup if you get a domain without a port. If you get a port #, it's a DNS host name.
+*/
+/*! \param chan Ast channel
+ \param host host name (return value)
+ \param hostlen Length of string "host"
+ \param port Port number (return value)
+ \param service Service tag for SRV lookup (like "_sip._udp" or "_stun._udp"
+*/
+extern int ast_get_srv(struct ast_channel *chan, char *host, int hostlen, int *port, const char *service);
+
+#endif /* _ASTERISK_SRV_H */
diff --git a/trunk/include/asterisk/stringfields.h b/trunk/include/asterisk/stringfields.h
new file mode 100644
index 000000000..65f1b53f9
--- /dev/null
+++ b/trunk/include/asterisk/stringfields.h
@@ -0,0 +1,307 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2006, Digium, Inc.
+ *
+ * Kevin P. Fleming <kpfleming@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ \brief String fields in structures
+
+ This file contains objects and macros used to manage string
+ fields in structures without requiring them to be allocated
+ as fixed-size buffers or requiring individual allocations for
+ for each field.
+
+ Using this functionality is quite simple. An example structure
+ with three fields is defined like this:
+
+ \code
+ struct sample_fields {
+ int x1;
+ AST_DECLARE_STRING_FIELDS(
+ AST_STRING_FIELD(foo);
+ AST_STRING_FIELD(bar);
+ AST_STRING_FIELD(blah);
+ );
+ long x2;
+ };
+ \endcode
+
+ When an instance of this structure is allocated (either statically or
+ dynamically), the fields and the pool of storage for them must be
+ initialized:
+
+ \code
+ struct sample_fields *x;
+
+ x = ast_calloc(1, sizeof(*x));
+ if (x == NULL || ast_string_field_init(x, 252)) {
+ if (x)
+ ast_free(x);
+ x = NULL;
+ ... handle error
+ }
+ \endcode
+
+ Fields will default to pointing to an empty string, and will revert to
+ that when ast_string_field_set() is called with a NULL argument.
+ A string field will \b never contain NULL (this feature is not used
+ in this code, but comes from external requirements).
+
+ ast_string_field_init(x, 0) will reset fields to the
+ initial value while keeping the pool allocated.
+
+ Reading the fields is much like using 'const char * const' fields in the
+ structure: you cannot write to the field or to the memory it points to
+ (XXX perhaps the latter is too much of a restriction since values
+ are not shared).
+
+ Writing to the fields must be done using the wrapper macros listed below;
+ and assignments are always by value (i.e. strings are copied):
+ * ast_string_field_set() stores a simple value;
+ * ast_string_field_build() builds the string using a printf-style;
+ * ast_string_field_build_va() is the varargs version of the above (for
+ portability reasons it uses two vararg);
+ * variants of these function allow passing a pointer to the field
+ as an argument.
+ \code
+ ast_string_field_set(x, foo, "infinite loop");
+ ast_string_field_set(x, foo, NULL); // set to an empty string
+ ast_string_field_ptr_set(x, &x->bar, "right way");
+
+ ast_string_field_build(x, blah, "%d %s", zipcode, city);
+ ast_string_field_ptr_build(x, &x->blah, "%d %s", zipcode, city);
+
+ ast_string_field_build_va(x, bar, fmt, args1, args2)
+ ast_string_field_ptr_build_va(x, &x->bar, fmt, args1, args2)
+ \endcode
+
+ When the structure instance is no longer needed, the fields
+ and their storage pool must be freed:
+
+ \code
+ ast_string_field_free_memory(x);
+ ast_free(x);
+ \endcode
+
+ This completes the API description.
+*/
+
+#ifndef _ASTERISK_STRINGFIELDS_H
+#define _ASTERISK_STRINGFIELDS_H
+
+#include "asterisk/inline_api.h"
+
+/*!
+ \internal
+ \brief An opaque type for managed string fields in structures
+
+ Don't declare instances of this type directly; use the AST_STRING_FIELD()
+ macro instead.
+*/
+typedef const char * ast_string_field;
+
+/*!
+ \internal
+ \brief A constant empty string used for fields that have no other value
+*/
+extern const char __ast_string_field_empty[];
+
+/*!
+ \internal
+ \brief Structure used to hold a pool of space for string fields
+*/
+struct ast_string_field_pool {
+ struct ast_string_field_pool *prev; /*!< pointer to the previous pool, if any */
+ char base[0]; /*!< storage space for the fields */
+};
+
+/*!
+ \internal
+ \brief Structure used to manage the storage for a set of string fields.
+ Because of the way pools are managed, we can only allocate from the topmost
+ pool, so the numbers here reflect just that.
+*/
+struct ast_string_field_mgr {
+ size_t size; /*!< the total size of the current pool */
+ size_t used; /*!< the space used in the current pool */
+};
+
+/*!
+ \internal
+ \brief Allocate space for a field
+ \param mgr Pointer to the pool manager structure
+ \param needed Amount of space needed for this field
+ \param fields Pointer to the first entry of the field array
+ \return NULL on failure, an address for the field on success.
+
+ This function will allocate the requested amount of space from
+ the field pool. If the requested amount of space is not available,
+ an additional pool will be allocated.
+*/
+ast_string_field __ast_string_field_alloc_space(struct ast_string_field_mgr *mgr,
+ struct ast_string_field_pool **pool_head, size_t needed);
+
+/*!
+ \internal
+ \brief Set a field to a complex (built) value
+ \param mgr Pointer to the pool manager structure
+ \param fields Pointer to the first entry of the field array
+ \param ptr Pointer to a field within the structure
+ \param format printf-style format string
+ \return nothing
+*/
+void __ast_string_field_ptr_build(struct ast_string_field_mgr *mgr,
+ struct ast_string_field_pool **pool_head,
+ const ast_string_field *ptr, const char *format, ...);
+
+/*!
+ \internal
+ \brief Set a field to a complex (built) value
+ \param mgr Pointer to the pool manager structure
+ \param fields Pointer to the first entry of the field array
+ \param ptr Pointer to a field within the structure
+ \param format printf-style format string
+ \param args va_list of the args for the format_string
+ \param args_again a copy of the first va_list for the sake of bsd not having a copy routine
+ \return nothing
+*/
+void __ast_string_field_ptr_build_va(struct ast_string_field_mgr *mgr,
+ struct ast_string_field_pool **pool_head,
+ const ast_string_field *ptr, const char *format, va_list a1, va_list a2);
+
+/*!
+ \brief Declare a string field
+ \param name The field name
+*/
+#define AST_STRING_FIELD(name) const ast_string_field name
+
+/*!
+ \brief Declare the fields needed in a structure
+ \param field_list The list of fields to declare, using AST_STRING_FIELD() for each one.
+ Internally, string fields are stored as a pointer to the head of the pool,
+ followed by individual string fields, and then a struct ast_string_field_mgr
+ which describes the space allocated.
+ We split the two variables so they can be used as markers around the
+ field_list, and this allows us to determine how many entries are in
+ the field, and play with them.
+ In particular, for writing to the fields, we rely on __field_mgr_pool to be
+ a non-const pointer, so we know it has the same size as ast_string_field,
+ and we can use it to locate the fields.
+*/
+#define AST_DECLARE_STRING_FIELDS(field_list) \
+ struct ast_string_field_pool *__field_mgr_pool; \
+ field_list \
+ struct ast_string_field_mgr __field_mgr
+
+/*!
+ \brief Initialize a field pool and fields
+ \param x Pointer to a structure containing fields
+ \param size Amount of storage to allocate.
+ Use 0 to reset fields to the default value,
+ and release all but the most recent pool.
+ size<0 (used internally) means free all pools.
+ \return 0 on success, non-zero on failure
+*/
+#define ast_string_field_init(x, size) \
+ __ast_string_field_init(&(x)->__field_mgr, &(x)->__field_mgr_pool, size)
+
+/*! \brief free all memory - to be called before destroying the object */
+#define ast_string_field_free_memory(x) \
+ __ast_string_field_init(&(x)->__field_mgr, &(x)->__field_mgr_pool, -1)
+
+/*! \internal \brief internal version of ast_string_field_init */
+int __ast_string_field_init(struct ast_string_field_mgr *mgr,
+ struct ast_string_field_pool **pool_head, int needed);
+
+/*!
+ \brief Set a field to a simple string value
+ \param x Pointer to a structure containing fields
+ \param ptr Pointer to a field within the structure
+ \param data String value to be copied into the field
+ \return nothing
+*/
+
+#define ast_string_field_ptr_set(x, ptr, data) do { \
+ const char *__d__ = (data); \
+ size_t __dlen__ = (__d__) ? strlen(__d__) : 0; \
+ const char **__p__ = (const char **)(ptr); \
+ if (__dlen__ == 0) \
+ *__p__ = __ast_string_field_empty; \
+ else if (__dlen__ <= strlen(*__p__)) \
+ strcpy((char *)*__p__, __d__); \
+ else if ( (*__p__ = __ast_string_field_alloc_space(&(x)->__field_mgr, &(x)->__field_mgr_pool, __dlen__ + 1) ) ) \
+ strcpy((char *)*__p__, __d__); \
+ } while (0)
+
+/*!
+ \brief Set a field to a simple string value
+ \param x Pointer to a structure containing fields
+ \param field Name of the field to set
+ \param data String value to be copied into the field
+ \return nothing
+*/
+#define ast_string_field_set(x, field, data) do { \
+ ast_string_field_ptr_set(x, &(x)->field, data); \
+ } while (0)
+
+
+/*!
+ \brief Set a field to a complex (built) value
+ \param x Pointer to a structure containing fields
+ \param ptr Pointer to a field within the structure
+ \param fmt printf-style format string
+ \param args Arguments for format string
+ \return nothing
+*/
+#define ast_string_field_ptr_build(x, ptr, fmt, args...) \
+ __ast_string_field_ptr_build(&(x)->__field_mgr, &(x)->__field_mgr_pool, ptr, fmt, args)
+
+/*!
+ \brief Set a field to a complex (built) value
+ \param x Pointer to a structure containing fields
+ \param field Name of the field to set
+ \param fmt printf-style format string
+ \param args Arguments for format string
+ \return nothing
+*/
+#define ast_string_field_build(x, field, fmt, args...) \
+ __ast_string_field_ptr_build(&(x)->__field_mgr, &(x)->__field_mgr_pool, &(x)->field, fmt, args)
+
+/*!
+ \brief Set a field to a complex (built) value with prebuilt va_lists.
+ \param x Pointer to a structure containing fields
+ \param ptr Pointer to a field within the structure
+ \param fmt printf-style format string
+ \param args1 Arguments for format string in va_list format
+ \param args2 a second copy of the va_list for the sake of bsd, with no va_list copy operation
+ \return nothing
+*/
+#define ast_string_field_ptr_build_va(x, ptr, fmt, args1, args2) \
+ __ast_string_field_ptr_build_va(&(x)->__field_mgr, &(x)->__field_mgr_pool, ptr, fmt, args1, args2)
+
+/*!
+ \brief Set a field to a complex (built) value
+ \param x Pointer to a structure containing fields
+ \param field Name of the field to set
+ \param fmt printf-style format string
+ \param args1 argument one
+ \param args2 argument two
+ \return nothing
+*/
+#define ast_string_field_build_va(x, field, fmt, args1, args2) \
+ __ast_string_field_ptr_build_va(&(x)->__field_mgr, &(x)->__field_mgr_pool, &(x)->field, fmt, args1, args2)
+
+#endif /* _ASTERISK_STRINGFIELDS_H */
diff --git a/trunk/include/asterisk/strings.h b/trunk/include/asterisk/strings.h
new file mode 100644
index 000000000..9646e94c2
--- /dev/null
+++ b/trunk/include/asterisk/strings.h
@@ -0,0 +1,691 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2006, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief String manipulation functions
+ */
+
+#ifndef _ASTERISK_STRINGS_H
+#define _ASTERISK_STRINGS_H
+
+#include "asterisk/inline_api.h"
+#include "asterisk/utils.h"
+#include "asterisk/threadstorage.h"
+
+/* You may see casts in this header that may seem useless but they ensure this file is C++ clean */
+
+static force_inline int ast_strlen_zero(const char *s)
+{
+ return (!s || (*s == '\0'));
+}
+
+/*! \brief returns the equivalent of logic or for strings:
+ * first one if not empty, otherwise second one.
+ */
+#define S_OR(a, b) (!ast_strlen_zero(a) ? (a) : (b))
+
+/*! \brief returns the equivalent of logic or for strings, with an additional boolean check:
+ * second one if not empty and first one is true, otherwise third one.
+ * example: S_COR(usewidget, widget, "<no widget>")
+ */
+#define S_COR(a, b, c) ((a && !ast_strlen_zero(b)) ? (b) : (c))
+
+/*!
+ \brief Gets a pointer to the first non-whitespace character in a string.
+ \param ast_skip_blanks function being used
+ \arg str the input string
+ \return a pointer to the first non-whitespace character
+ */
+AST_INLINE_API(
+char *ast_skip_blanks(const char *str),
+{
+ while (*str && ((unsigned char) *str) < 33)
+ str++;
+ return (char *)str;
+}
+)
+
+/*!
+ \brief Trims trailing whitespace characters from a string.
+ \param ast_skip_blanks function being used
+ \arg str the input string
+ \return a pointer to the modified string
+ */
+AST_INLINE_API(
+char *ast_trim_blanks(char *str),
+{
+ char *work = str;
+
+ if (work) {
+ work += strlen(work) - 1;
+ /* It's tempting to only want to erase after we exit this loop,
+ but since ast_trim_blanks *could* receive a constant string
+ (which we presumably wouldn't have to touch), we shouldn't
+ actually set anything unless we must, and it's easier just
+ to set each position to \0 than to keep track of a variable
+ for it */
+ while ((work >= str) && ((unsigned char) *work) < 33)
+ *(work--) = '\0';
+ }
+ return str;
+}
+)
+
+/*!
+ \brief Gets a pointer to first whitespace character in a string.
+ \param ast_skip_noblanks function being used
+ \arg str the input string
+ \return a pointer to the first whitespace character
+ */
+AST_INLINE_API(
+char *ast_skip_nonblanks(char *str),
+{
+ while (*str && ((unsigned char) *str) > 32)
+ str++;
+ return str;
+}
+)
+
+/*!
+ \brief Strip leading/trailing whitespace from a string.
+ \param ast_strip function ast_strip being used.
+ \arg s The string to be stripped (will be modified).
+ \return The stripped string.
+
+ This functions strips all leading and trailing whitespace
+ characters from the input string, and returns a pointer to
+ the resulting string. The string is modified in place.
+*/
+AST_INLINE_API(
+char *ast_strip(char *s),
+{
+ s = ast_skip_blanks(s);
+ if (s)
+ ast_trim_blanks(s);
+ return s;
+}
+)
+
+/*!
+ \brief Strip leading/trailing whitespace and quotes from a string.
+ \param s The string to be stripped (will be modified).
+ \param beg_quotes The list of possible beginning quote characters.
+ \param end_quotes The list of matching ending quote characters.
+ \return The stripped string.
+
+ This functions strips all leading and trailing whitespace
+ characters from the input string, and returns a pointer to
+ the resulting string. The string is modified in place.
+
+ It can also remove beginning and ending quote (or quote-like)
+ characters, in matching pairs. If the first character of the
+ string matches any character in beg_quotes, and the last
+ character of the string is the matching character in
+ end_quotes, then they are removed from the string.
+
+ Examples:
+ \code
+ ast_strip_quoted(buf, "\"", "\"");
+ ast_strip_quoted(buf, "'", "'");
+ ast_strip_quoted(buf, "[{(", "]})");
+ \endcode
+ */
+char *ast_strip_quoted(char *s, const char *beg_quotes, const char *end_quotes);
+
+/*!
+ \brief Strip backslash for "escaped" semicolons.
+ \brief s The string to be stripped (will be modified).
+ \return The stripped string.
+ */
+char *ast_unescape_semicolon(char *s);
+
+/*!
+ \brief Convert some C escape sequences (\b\f\n\r\t) into the
+ equivalent characters.
+ \brief s The string to be converted (will be modified).
+ \return The converted string.
+ */
+char *ast_unescape_c(char *s);
+
+/*!
+ \brief Size-limited null-terminating string copy.
+ \arg dst The destination buffer.
+ \arg src The source string
+ \arg size The size of the destination buffer
+ \return Nothing.
+
+ This is similar to \a strncpy, with two important differences:
+ - the destination buffer will \b always be null-terminated
+ - the destination buffer is not filled with zeros past the copied string length
+ These differences make it slightly more efficient, and safer to use since it will
+ not leave the destination buffer unterminated. There is no need to pass an artificially
+ reduced buffer size to this function (unlike \a strncpy), and the buffer does not need
+ to be initialized to zeroes prior to calling this function.
+*/
+AST_INLINE_API(
+void ast_copy_string(char *dst, const char *src, size_t size),
+{
+ while (*src && size) {
+ *dst++ = *src++;
+ size--;
+ }
+ if (__builtin_expect(!size, 0))
+ dst--;
+ *dst = '\0';
+}
+)
+
+
+/*!
+ \brief Build a string in a buffer, designed to be called repeatedly
+
+ \note This method is not recommended. New code should use ast_str_*() instead.
+
+ This is a wrapper for snprintf, that properly handles the buffer pointer
+ and buffer space available.
+
+ \arg buffer current position in buffer to place string into (will be updated on return)
+ \arg space remaining space in buffer (will be updated on return)
+ \arg fmt printf-style format string
+ \retval 0 on success
+ \retval non-zero on failure.
+*/
+int ast_build_string(char **buffer, size_t *space, const char *fmt, ...) __attribute__ ((format (printf, 3, 4)));
+
+/*!
+ \brief Build a string in a buffer, designed to be called repeatedly
+
+ This is a wrapper for snprintf, that properly handles the buffer pointer
+ and buffer space available.
+
+ \return 0 on success, non-zero on failure.
+ \param buffer current position in buffer to place string into (will be updated on return)
+ \param space remaining space in buffer (will be updated on return)
+ \param fmt printf-style format string
+ \param ap varargs list of arguments for format
+*/
+int ast_build_string_va(char **buffer, size_t *space, const char *fmt, va_list ap);
+
+/*!
+ * \brief Make sure something is true.
+ * Determine if a string containing a boolean value is "true".
+ * This function checks to see whether a string passed to it is an indication of an "true" value.
+ * It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
+ *
+ * \retval 0 if val is a NULL pointer.
+ * \retval -1 if "true".
+ * \retval 0 otherwise.
+ */
+int ast_true(const char *val);
+
+/*!
+ * \brief Make sure something is false.
+ * Determine if a string containing a boolean value is "false".
+ * This function checks to see whether a string passed to it is an indication of an "false" value.
+ * It checks to see if the string is "no", "false", "n", "f", "off" or "0".
+ *
+ * \retval 0 if val is a NULL pointer.
+ * \retval -1 if "true".
+ * \retval 0 otherwise.
+ */
+int ast_false(const char *val);
+
+/*
+ * \brief Join an array of strings into a single string.
+ * \param s the resulting string buffer
+ * \param len the length of the result buffer, s
+ * \param w an array of strings to join.
+ *
+ * This function will join all of the strings in the array 'w' into a single
+ * string. It will also place a space in the result buffer in between each
+ * string from 'w'.
+*/
+void ast_join(char *s, size_t len, char * const w[]);
+
+/*
+ \brief Parse a time (integer) string.
+ \param src String to parse
+ \param dst Destination
+ \param _default Value to use if the string does not contain a valid time
+ \param consumed The number of characters 'consumed' in the string by the parse (see 'man sscanf' for details)
+ \retval 0 on success
+ \retval non-zero on failure.
+*/
+int ast_get_time_t(const char *src, time_t *dst, time_t _default, int *consumed);
+
+/*
+ \brief Parse a time (float) string.
+ \param src String to parse
+ \param dst Destination
+ \param _default Value to use if the string does not contain a valid time
+ \param consumed The number of characters 'consumed' in the string by the parse (see 'man sscanf' for details)
+ \return zero on success, non-zero on failure
+*/
+int ast_get_timeval(const char *src, struct timeval *tv, struct timeval _default, int *consumed);
+
+/*!
+ * Support for dynamic strings.
+ *
+ * A dynamic string is just a C string prefixed by a few control fields
+ * that help setting/appending/extending it using a printf-like syntax.
+ *
+ * One should never declare a variable with this type, but only a pointer
+ * to it, e.g.
+ *
+ * struct ast_str *ds;
+ *
+ * The pointer can be initialized with the following:
+ *
+ * ds = ast_str_create(init_len);
+ * creates a malloc()'ed dynamic string;
+ *
+ * ds = ast_str_alloca(init_len);
+ * creates a string on the stack (not very dynamic!).
+ *
+ * ds = ast_str_thread_get(ts, init_len)
+ * creates a malloc()'ed dynamic string associated to
+ * the thread-local storage key ts
+ *
+ * Finally, the string can be manipulated with the following:
+ *
+ * ast_str_set(&buf, max_len, fmt, ...)
+ * ast_str_append(&buf, max_len, fmt, ...)
+ *
+ * and their varargs variant
+ *
+ * ast_str_set_va(&buf, max_len, ap)
+ * ast_str_append_va(&buf, max_len, ap)
+ *
+ * \arg max_len The maximum allowed length, reallocating if needed.
+ * 0 means unlimited, -1 means "at most the available space"
+ *
+ * \return All the functions return <0 in case of error, or the
+ * length of the string added to the buffer otherwise.
+ */
+
+/*! \brief The descriptor of a dynamic string
+ * XXX storage will be optimized later if needed
+ * We use the ts field to indicate the type of storage.
+ * Three special constants indicate malloc, alloca() or static
+ * variables, all other values indicate a
+ * struct ast_threadstorage pointer.
+ */
+struct ast_str {
+ size_t len; /*!< The current maximum length of the string */
+ size_t used; /*!< Amount of space used */
+ struct ast_threadstorage *ts; /*!< What kind of storage is this ? */
+#define DS_MALLOC ((struct ast_threadstorage *)1)
+#define DS_ALLOCA ((struct ast_threadstorage *)2)
+#define DS_STATIC ((struct ast_threadstorage *)3) /* not supported yet */
+ char str[0]; /*!< The string buffer */
+};
+
+/*!
+ * \brief Create a malloc'ed dynamic length string
+ *
+ * \arg init_len This is the initial length of the string buffer
+ *
+ * \return This function returns a pointer to the dynamic string length. The
+ * result will be NULL in the case of a memory allocation error.
+ *
+ * \note The result of this function is dynamically allocated memory, and must
+ * be free()'d after it is no longer needed.
+ */
+AST_INLINE_API(
+struct ast_str * attribute_malloc ast_str_create(size_t init_len),
+{
+ struct ast_str *buf;
+
+ buf = (struct ast_str *)ast_calloc(1, sizeof(*buf) + init_len);
+ if (buf == NULL)
+ return NULL;
+
+ buf->len = init_len;
+ buf->used = 0;
+ buf->ts = DS_MALLOC;
+
+ return buf;
+}
+)
+
+/*! \brief Reset the content of a dynamic string.
+ * Useful before a series of ast_str_append.
+ */
+AST_INLINE_API(
+void ast_str_reset(struct ast_str *buf),
+{
+ if (buf) {
+ buf->used = 0;
+ if (buf->len)
+ buf->str[0] = '\0';
+ }
+}
+)
+
+/*
+ * AST_INLINE_API() is a macro that takes a block of code as an argument.
+ * Using preprocessor #directives in the argument is not supported by all
+ * compilers, and it is a bit of an obfuscation anyways, so avoid it.
+ * As a workaround, define a macro that produces either its argument
+ * or nothing, and use that instead of #ifdef/#endif within the
+ * argument to AST_INLINE_API().
+ */
+#if defined(DEBUG_THREADLOCALS)
+#define _DB1(x) x
+#else
+#define _DB1(x)
+#endif
+
+/*!
+ * Make space in a new string (e.g. to read in data from a file)
+ */
+AST_INLINE_API(
+int ast_str_make_space(struct ast_str **buf, size_t new_len),
+{
+ _DB1(struct ast_str *old_buf = *buf;)
+
+ if (new_len <= (*buf)->len)
+ return 0; /* success */
+ if ((*buf)->ts == DS_ALLOCA || (*buf)->ts == DS_STATIC)
+ return -1; /* cannot extend */
+ *buf = (struct ast_str *)ast_realloc(*buf, new_len + sizeof(struct ast_str));
+ if (*buf == NULL) /* XXX watch out, we leak memory here */
+ return -1;
+ if ((*buf)->ts != DS_MALLOC) {
+ pthread_setspecific((*buf)->ts->key, *buf);
+ _DB1(__ast_threadstorage_object_replace(old_buf, *buf, new_len + sizeof(struct ast_str));)
+ }
+
+ (*buf)->len = new_len;
+ return 0;
+}
+)
+
+#define ast_str_alloca(init_len) \
+ ({ \
+ struct ast_str *buf; \
+ buf = alloca(sizeof(*buf) + init_len); \
+ buf->len = init_len; \
+ buf->used = 0; \
+ buf->ts = DS_ALLOCA; \
+ buf->str[0] = '\0'; \
+ (buf); \
+ })
+
+/*!
+ * \brief Retrieve a thread locally stored dynamic string
+ *
+ * \arg ts This is a pointer to the thread storage structure declared by using
+ * the AST_THREADSTORAGE macro. If declared with
+ * AST_THREADSTORAGE(my_buf, my_buf_init), then this argument would be
+ * (&my_buf).
+ * \arg init_len This is the initial length of the thread's dynamic string. The
+ * current length may be bigger if previous operations in this thread have
+ * caused it to increase.
+ *
+ * \return This function will return the thread locally stored dynamic string
+ * associated with the thread storage management variable passed as the
+ * first argument.
+ * The result will be NULL in the case of a memory allocation error.
+ *
+ * Example usage:
+ * \code
+ * AST_THREADSTORAGE(my_str, my_str_init);
+ * #define MY_STR_INIT_SIZE 128
+ * ...
+ * void my_func(const char *fmt, ...)
+ * {
+ * struct ast_str *buf;
+ *
+ * if (!(buf = ast_str_thread_get(&my_str, MY_STR_INIT_SIZE)))
+ * return;
+ * ...
+ * }
+ * \endcode
+ */
+#if !defined(DEBUG_THREADLOCALS)
+AST_INLINE_API(
+struct ast_str *ast_str_thread_get(struct ast_threadstorage *ts,
+ size_t init_len),
+{
+ struct ast_str *buf;
+
+ buf = (struct ast_str *)ast_threadstorage_get(ts, sizeof(*buf) + init_len);
+ if (buf == NULL)
+ return NULL;
+
+ if (!buf->len) {
+ buf->len = init_len;
+ buf->used = 0;
+ buf->ts = ts;
+ }
+
+ return buf;
+}
+)
+#else /* defined(DEBUG_THREADLOCALS) */
+AST_INLINE_API(
+struct ast_str *__ast_str_thread_get(struct ast_threadstorage *ts,
+ size_t init_len, const char *file, const char *function, unsigned int line),
+{
+ struct ast_str *buf;
+
+ buf = (struct ast_str *)__ast_threadstorage_get(ts, sizeof(*buf) + init_len, file, function, line);
+ if (buf == NULL)
+ return NULL;
+
+ if (!buf->len) {
+ buf->len = init_len;
+ buf->used = 0;
+ buf->ts = ts;
+ }
+
+ return buf;
+}
+)
+
+#define ast_str_thread_get(ts, init_len) __ast_str_thread_get(ts, init_len, __FILE__, __PRETTY_FUNCTION__, __LINE__)
+#endif /* defined(DEBUG_THREADLOCALS) */
+
+/*!
+ * \brief Error codes from __ast_str_helper()
+ * The undelying processing to manipulate dynamic string is done
+ * by __ast_str_helper(), which can return a success, a
+ * permanent failure (e.g. no memory), or a temporary one (when
+ * the string needs to be reallocated, and we must run va_start()
+ * again; XXX this convoluted interface is only here because
+ * FreeBSD 4 lacks va_copy, but this will be fixed and the
+ * interface simplified).
+ */
+enum {
+ /*! An error has occured and the contents of the dynamic string
+ * are undefined */
+ AST_DYNSTR_BUILD_FAILED = -1,
+ /*! The buffer size for the dynamic string had to be increased, and
+ * __ast_str_helper() needs to be called again after
+ * a va_end() and va_start().
+ */
+ AST_DYNSTR_BUILD_RETRY = -2
+};
+
+/*!
+ * \brief Set a dynamic string from a va_list
+ *
+ * \arg buf This is the address of a pointer to a struct ast_str.
+ * If it is retrieved using ast_str_thread_get, the
+ struct ast_threadstorage pointer will need to
+ * be updated in the case that the buffer has to be reallocated to
+ * accommodate a longer string than what it currently has space for.
+ * \arg max_len This is the maximum length to allow the string buffer to grow
+ * to. If this is set to 0, then there is no maximum length.
+ * \arg fmt This is the format string (printf style)
+ * \arg ap This is the va_list
+ *
+ * \return The return value of this function is the same as that of the printf
+ * family of functions.
+ *
+ * Example usage (the first part is only for thread-local storage)
+ * \code
+ * AST_THREADSTORAGE(my_str, my_str_init);
+ * #define MY_STR_INIT_SIZE 128
+ * ...
+ * void my_func(const char *fmt, ...)
+ * {
+ * struct ast_str *buf;
+ * va_list ap;
+ *
+ * if (!(buf = ast_str_thread_get(&my_str, MY_STR_INIT_SIZE)))
+ * return;
+ * ...
+ * va_start(fmt, ap);
+ * ast_str_set_va(&buf, 0, fmt, ap);
+ * va_end(ap);
+ *
+ * printf("This is the string we just built: %s\n", buf->str);
+ * ...
+ * }
+ * \endcode
+ *
+ * \note: the following two functions must be implemented as macros
+ * because we must do va_end()/va_start() on the original arguments.
+ */
+#define ast_str_set_va(buf, max_len, fmt, ap) \
+ ({ \
+ int __res; \
+ while ((__res = __ast_str_helper(buf, max_len, \
+ 0, fmt, ap)) == AST_DYNSTR_BUILD_RETRY) { \
+ va_end(ap); \
+ va_start(ap, fmt); \
+ } \
+ (__res); \
+ })
+
+/*!
+ * \brief Append to a dynamic string using a va_list
+ *
+ * Same as ast_str_set_va(), but append to the current content.
+ */
+#define ast_str_append_va(buf, max_len, fmt, ap) \
+ ({ \
+ int __res; \
+ while ((__res = __ast_str_helper(buf, max_len, \
+ 1, fmt, ap)) == AST_DYNSTR_BUILD_RETRY) { \
+ va_end(ap); \
+ va_start(ap, fmt); \
+ } \
+ (__res); \
+ })
+
+/*!
+ * \brief Core functionality of ast_str_(set|append)_va
+ *
+ * The arguments to this function are the same as those described for
+ * ast_str_set_va except for an addition argument, append.
+ * If append is non-zero, this will append to the current string instead of
+ * writing over it.
+ *
+ * In the case that this function is called and the buffer was not large enough
+ * to hold the result, the partial write will be truncated, and the result
+ * AST_DYNSTR_BUILD_RETRY will be returned to indicate that the buffer size
+ * was increased, and the function should be called a second time.
+ *
+ * A return of AST_DYNSTR_BUILD_FAILED indicates a memory allocation error.
+ *
+ * A return value greater than or equal to zero indicates the number of
+ * characters that have been written, not including the terminating '\0'.
+ * In the append case, this only includes the number of characters appended.
+ *
+ * \note This function should never need to be called directly. It should
+ * through calling one of the other functions or macros defined in this
+ * file.
+ */
+int __ast_str_helper(struct ast_str **buf, size_t max_len,
+ int append, const char *fmt, va_list ap);
+
+/*!
+ * \brief Set a dynamic string using variable arguments
+ *
+ * \arg buf This is the address of a pointer to a struct ast_str which should
+ * have been retrieved using ast_str_thread_get. It will need to
+ * be updated in the case that the buffer has to be reallocated to
+ * accomodate a longer string than what it currently has space for.
+ * \arg max_len This is the maximum length to allow the string buffer to grow
+ * to. If this is set to 0, then there is no maximum length.
+ * If set to -1, we are bound to the current maximum length.
+ * \arg fmt This is the format string (printf style)
+ *
+ * \return The return value of this function is the same as that of the printf
+ * family of functions.
+ *
+ * All the rest is the same as ast_str_set_va()
+ */
+AST_INLINE_API(
+int __attribute__ ((format (printf, 3, 4))) ast_str_set(
+ struct ast_str **buf, size_t max_len, const char *fmt, ...),
+{
+ int res;
+ va_list ap;
+
+ va_start(ap, fmt);
+ res = ast_str_set_va(buf, max_len, fmt, ap);
+ va_end(ap);
+
+ return res;
+}
+)
+
+/*!
+ * \brief Append to a thread local dynamic string
+ *
+ * The arguments, return values, and usage of this function are the same as
+ * ast_str_set(), but the new data is appended to the current value.
+ */
+AST_INLINE_API(
+int __attribute__ ((format (printf, 3, 4))) ast_str_append(
+ struct ast_str **buf, size_t max_len, const char *fmt, ...),
+{
+ int res;
+ va_list ap;
+
+ va_start(ap, fmt);
+ res = ast_str_append_va(buf, max_len, fmt, ap);
+ va_end(ap);
+
+ return res;
+}
+)
+
+/*!
+ * \brief Compute a hash value on a string
+ *
+ * This famous hash algorithm was written by Dan Bernstein and is
+ * commonly used.
+ *
+ * http://www.cse.yorku.ca/~oz/hash.html
+ */
+static force_inline int ast_str_hash(const char *str)
+{
+ int hash = 5381;
+
+ while (*str)
+ hash = hash * 33 ^ *str++;
+
+ return abs(hash);
+}
+
+#endif /* _ASTERISK_STRINGS_H */
diff --git a/trunk/include/asterisk/tcptls.h b/trunk/include/asterisk/tcptls.h
new file mode 100644
index 000000000..fe4743f33
--- /dev/null
+++ b/trunk/include/asterisk/tcptls.h
@@ -0,0 +1,166 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2006, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*!
+ * \file server.h
+ *
+ * \brief Generic support for tcp/tls servers in Asterisk.
+ * \note In order to have TLS/SSL support, we need the openssl libraries.
+ * Still we can decide whether or not to use them by commenting
+ * in or out the DO_SSL macro.
+ * TLS/SSL support is basically implemented by reading from a config file
+ * (currently http.conf) the names of the certificate and cipher to use,
+ * and then run ssl_setup() to create an appropriate SSL_CTX (ssl_ctx)
+ * If we support multiple domains, presumably we need to read multiple
+ * certificates.
+ * When we are requested to open a TLS socket, we run make_file_from_fd()
+ * on the socket, to do the necessary setup. At the moment the context's name
+ * is hardwired in the function, but we can certainly make it into an extra
+ * parameter to the function.
+ * We declare most of ssl support variables unconditionally,
+ * because their number is small and this simplifies the code.
+ *
+ * \note: the ssl-support variables (ssl_ctx, do_ssl, certfile, cipher)
+ * and their setup should be moved to a more central place, e.g. asterisk.conf
+ * and the source files that processes it. Similarly, ssl_setup() should
+ * be run earlier in the startup process so modules have it available.
+ *
+ */
+
+
+#ifndef _ASTERISK_SERVER_H
+#define _ASTERISK_SERVER_H
+
+#include "asterisk/utils.h"
+
+#if defined(HAVE_OPENSSL) && (defined(HAVE_FUNOPEN) || defined(HAVE_FOPENCOOKIE))
+#define DO_SSL /* comment in/out if you want to support ssl */
+#endif
+
+#ifdef DO_SSL
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+#else
+/* declare dummy types so we can define a pointer to them */
+typedef struct {} SSL;
+typedef struct {} SSL_CTX;
+#endif /* DO_SSL */
+
+/*! SSL support */
+#define AST_CERTFILE "asterisk.pem"
+
+enum ast_ssl_flags {
+ /*! Verify certificate when acting as server */
+ AST_SSL_VERIFY_CLIENT = (1 << 0),
+ /*! Don't verify certificate when connecting to a server */
+ AST_SSL_DONT_VERIFY_SERVER = (1 << 1),
+ /*! Don't compare "Common Name" against IP or hostname */
+ AST_SSL_IGNORE_COMMON_NAME = (1 << 2)
+};
+
+struct ast_tls_config {
+ int enabled;
+ char *certfile;
+ char *cipher;
+ char *cafile;
+ char *capath;
+ struct ast_flags flags;
+ SSL_CTX *ssl_ctx;
+};
+
+/*!
+ * The following code implements a generic mechanism for starting
+ * services on a TCP or TLS socket.
+ * The service is configured in the struct server_args, and
+ * then started by calling server_start(desc) on the descriptor.
+ * server_start() first verifies if an instance of the service is active,
+ * and in case shuts it down. Then, if the service must be started, creates
+ * a socket and a thread in charge of doing the accept().
+ *
+ * The body of the thread is desc->accept_fn(desc), which the user can define
+ * freely. We supply a sample implementation, server_root(), structured as an
+ * infinite loop. At the beginning of each iteration it runs periodic_fn()
+ * if defined (e.g. to perform some cleanup etc.) then issues a poll()
+ * or equivalent with a timeout of 'poll_timeout' milliseconds, and if the
+ * following accept() is successful it creates a thread in charge of
+ * running the session, whose body is desc->worker_fn(). The argument of
+ * worker_fn() is a struct server_instance, which contains the address
+ * of the other party, a pointer to desc, the file descriptors (fd) on which
+ * we can do a select/poll (but NOT IO/, and a FILE *on which we can do I/O.
+ * We have both because we want to support plain and SSL sockets, and
+ * going through a FILE *lets us provide the encryption/decryption
+ * on the stream without using an auxiliary thread.
+ *
+ * NOTE: in order to let other parts of asterisk use these services,
+ * we need to do the following:
+ * + move struct server_instance and struct server_args to
+ * a common header file, together with prototypes for
+ * server_start() and server_root().
+ */
+
+/*!
+ * describes a server instance
+ */
+struct server_instance {
+ FILE *f; /* fopen/funopen result */
+ int fd; /* the socket returned by accept() */
+ SSL *ssl; /* ssl state */
+// iint (*ssl_setup)(SSL *);
+ int client;
+ struct sockaddr_in requestor;
+ struct server_args *parent;
+};
+
+/*!
+ * arguments for the accepting thread
+ */
+struct server_args {
+ struct sockaddr_in sin;
+ struct sockaddr_in oldsin;
+ char hostname[MAXHOSTNAMELEN]; /* only necessary for SSL clients so we can compare to common name */
+ struct ast_tls_config *tls_cfg; /* points to the SSL configuration if any */
+ int accept_fd;
+ int poll_timeout;
+ pthread_t master;
+ void *(*accept_fn)(void *); /* the function in charge of doing the accept */
+ void (*periodic_fn)(void *);/* something we may want to run before after select on the accept socket */
+ void *(*worker_fn)(void *); /* the function in charge of doing the actual work */
+ const char *name;
+};
+
+#if defined(HAVE_FUNOPEN)
+#define HOOK_T int
+#define LEN_T int
+#else
+#define HOOK_T ssize_t
+#define LEN_T size_t
+#endif
+
+struct server_instance *client_start(struct server_args *desc);
+
+void *server_root(void *);
+void server_start(struct server_args *desc);
+void server_stop(struct server_args *desc);
+int ssl_setup(struct ast_tls_config *cfg);
+
+void *ast_make_file_from_fd(void *data);
+
+HOOK_T server_read(struct server_instance *ser, void *buf, size_t count);
+HOOK_T server_write(struct server_instance *ser, void *buf, size_t count);
+
+#endif /* _ASTERISK_SERVER_H */
diff --git a/trunk/include/asterisk/tdd.h b/trunk/include/asterisk/tdd.h
new file mode 100644
index 000000000..6fb7e3e27
--- /dev/null
+++ b/trunk/include/asterisk/tdd.h
@@ -0,0 +1,82 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2005, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief TTY/TDD Generation support
+ * \note Includes code and algorithms from the Zapata library.
+ */
+
+#ifndef _ASTERISK_TDD_H
+#define _ASTERISK_TDD_H
+
+#define TDD_BYTES_PER_CHAR 2700
+
+struct tdd_state;
+typedef struct tdd_state TDDSTATE;
+
+/*! CallerID Initialization
+ * Initializes the TDD system. Mostly stuff for inverse FFT
+ */
+void tdd_init(void);
+
+/*! Generates a CallerID FSK stream in ulaw format suitable for transmission.
+ * \param tdd tdd structure
+ * \param buf Buffer to use. This needs to be large enough to accomodate all the generated samples.
+ * \param string This is the string to send.
+ * This function creates a stream of TDD data in ulaw format. It returns the size
+ * (in bytes) of the data (if it returns a size of 0, there is probably an error)
+*/
+int tdd_generate(struct tdd_state *tdd, unsigned char *buf, const char *string);
+
+/*! Create a TDD state machine
+ * This function returns a malloc'd instance of the tdd_state data structure.
+ * Returns a pointer to a malloc'd tdd_state structure, or NULL on error.
+ */
+struct tdd_state *tdd_new(void);
+
+/*! Read samples into the state machine, and return character (if any).
+ * \param tdd Which state machine to act upon
+ * \param ubuf containing your samples
+ * \param samples number of samples contained within the buffer.
+ *
+ * Send received audio to the TDD demodulator.
+ * Returns -1 on error, 0 for "needs more samples",
+ * and > 0 (the character) if reception of a character is complete.
+ */
+int tdd_feed(struct tdd_state *tdd, unsigned char *ubuf, int samples);
+
+/*! Free a TDD state machine
+ * \param tdd This is the tdd_state state machine to free
+ * This function frees tdd_state tdd.
+ */
+void tdd_free(struct tdd_state *tdd);
+
+/*! Generate Echo Canceller disable tone (2100HZ)
+ * \param outbuf This is the buffer to receive the tone data
+ * \param len This is the length (in samples) of the tone data to generate
+ * Returns 0 if no error, and -1 if error.
+ */
+int ast_tdd_gen_ecdisa(unsigned char *outbuf, int len);
+
+
+/*! Generate hold tone
+ * \param outbuf This is the buffer to receive the tone data
+*/
+int tdd_gen_holdtone(unsigned char* outbuf);
+
+#endif /* _ASTERISK_TDD_H */
diff --git a/trunk/include/asterisk/term.h b/trunk/include/asterisk/term.h
new file mode 100644
index 000000000..3277f0042
--- /dev/null
+++ b/trunk/include/asterisk/term.h
@@ -0,0 +1,85 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2005, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief Handy terminal functions for vt* terms
+ */
+
+#ifndef _ASTERISK_TERM_H
+#define _ASTERISK_TERM_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+#define ESC 0x1b
+
+/*! \name Terminal Attributes
+*/
+/*@{ */
+#define ATTR_RESET 0
+#define ATTR_BRIGHT 1
+#define ATTR_DIM 2
+#define ATTR_UNDER 4
+#define ATTR_BLINK 5
+#define ATTR_REVER 7
+#define ATTR_HIDDEN 8
+/*@} */
+
+/*! \name Terminal Colors
+*/
+/*@{ */
+#define COLOR_BLACK 30
+#define COLOR_GRAY (30 | 128)
+#define COLOR_RED 31
+#define COLOR_BRRED (31 | 128)
+#define COLOR_GREEN 32
+#define COLOR_BRGREEN (32 | 128)
+#define COLOR_BROWN 33
+#define COLOR_YELLOW (33 | 128)
+#define COLOR_BLUE 34
+#define COLOR_BRBLUE (34 | 128)
+#define COLOR_MAGENTA 35
+#define COLOR_BRMAGENTA (35 | 128)
+#define COLOR_CYAN 36
+#define COLOR_BRCYAN (36 | 128)
+#define COLOR_WHITE 37
+#define COLOR_BRWHITE (37 | 128)
+/*@} */
+
+char *term_color(char *outbuf, const char *inbuf, int fgcolor, int bgcolor, int maxout);
+
+char *term_color_code(char *outbuf, int fgcolor, int bgcolor, int maxout);
+
+char *term_strip(char *outbuf, char *inbuf, int maxout);
+
+void term_filter_escapes(char *line);
+
+char *term_prompt(char *outbuf, const char *inbuf, int maxout);
+
+char *term_prep(void);
+
+char *term_end(void);
+
+char *term_quit(void);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _ASTERISK_TERM_H */
diff --git a/trunk/include/asterisk/threadstorage.h b/trunk/include/asterisk/threadstorage.h
new file mode 100644
index 000000000..5e6b3c348
--- /dev/null
+++ b/trunk/include/asterisk/threadstorage.h
@@ -0,0 +1,212 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2006, Digium, Inc.
+ *
+ * Russell Bryant <russell@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*!
+ * \file threadstorage.h
+ * \author Russell Bryant <russell@digium.com>
+ * \brief Definitions to aid in the use of thread local storage
+ *
+ * \arg \ref AstThreadStorage
+ */
+
+/*!
+ * \page AstThreadStorage The Asterisk Thread Storage API
+ *
+ *
+ * The POSIX threads (pthreads) API provides the ability to define thread
+ * specific data. The functions and structures defined here are intended
+ * to centralize the code that is commonly used when using thread local
+ * storage.
+ *
+ * The motivation for using this code in Asterisk is for situations where
+ * storing data on a thread-specific basis can provide some amount of
+ * performance benefit. For example, there are some call types in Asterisk
+ * where ast_frame structures must be allocated very rapidly (easily 50, 100,
+ * 200 times a second). Instead of doing the equivalent of that many calls
+ * to malloc() and free() per second, thread local storage is used to keep a
+ * list of unused frame structures so that they can be continuously reused.
+ *
+ * - \ref threadstorage.h
+ */
+
+#ifndef ASTERISK_THREADSTORAGE_H
+#define ASTERISK_THREADSTORAGE_H
+
+#include "asterisk/utils.h"
+#include "asterisk/inline_api.h"
+
+/*!
+ * \brief data for a thread locally stored variable
+ */
+struct ast_threadstorage {
+ pthread_once_t once; /*!< Ensure that the key is only initialized by one thread */
+ pthread_key_t key; /*!< The key used to retrieve this thread's data */
+ void (*key_init)(void); /*!< The function that initializes the key */
+ int (*custom_init)(void *); /*!< Custom initialization function specific to the object */
+};
+
+#ifdef SOLARIS
+#define THREADSTORAGE_ONCE_INIT {PTHREAD_ONCE_INIT}
+#else
+#define THREADSTORAGE_ONCE_INIT PTHREAD_ONCE_INIT
+#endif
+
+#if defined(DEBUG_THREADLOCALS)
+void __ast_threadstorage_object_add(void *key, size_t len, const char *file, const char *function, unsigned int line);
+void __ast_threadstorage_object_remove(void *key);
+void __ast_threadstorage_object_replace(void *key_old, void *key_new, size_t len);
+#endif /* defined(DEBUG_THREADLOCALS) */
+
+/*!
+ * \brief Define a thread storage variable
+ *
+ * \arg name The name of the thread storage object
+ *
+ * This macro would be used to declare an instance of thread storage in a file.
+ *
+ * Example usage:
+ * \code
+ * AST_THREADSTORAGE(my_buf);
+ * \endcode
+ */
+#define AST_THREADSTORAGE(name) \
+ AST_THREADSTORAGE_CUSTOM(name, NULL, ast_free_ptr)
+
+/*!
+ * \brief Define a thread storage variable, with custom initialization and cleanup
+ *
+ * \arg name The name of the thread storage object
+ * \arg init This is a custom function that will be called after each thread specific
+ * object is allocated, with the allocated block of memory passed
+ * as the argument.
+ * \arg cleanup This is a custom function that will be called instead of ast_free
+ * when the thread goes away. Note that if this is used, it *MUST*
+ * call free on the allocated memory.
+ *
+ * Example usage:
+ * \code
+ * AST_THREADSTORAGE_CUSTOM(my_buf, my_init, my_cleanup);
+ * \endcode
+ */
+#if !defined(DEBUG_THREADLOCALS)
+#define AST_THREADSTORAGE_CUSTOM(name, c_init, c_cleanup) \
+static void __init_##name(void); \
+static struct ast_threadstorage name = { \
+ .once = THREADSTORAGE_ONCE_INIT, \
+ .key_init = __init_##name, \
+ .custom_init = c_init, \
+}; \
+static void __init_##name(void) \
+{ \
+ pthread_key_create(&(name).key, c_cleanup); \
+}
+#else /* defined(DEBUG_THREADLOCALS) */
+#define AST_THREADSTORAGE_CUSTOM(name, c_init, c_cleanup) \
+static void __init_##name(void); \
+static struct ast_threadstorage name = { \
+ .once = THREADSTORAGE_ONCE_INIT, \
+ .key_init = __init_##name, \
+ .custom_init = c_init, \
+}; \
+static void __cleanup_##name(void *data) \
+{ \
+ __ast_threadstorage_object_remove(data); \
+ c_cleanup(data); \
+} \
+static void __init_##name(void) \
+{ \
+ pthread_key_create(&(name).key, __cleanup_##name); \
+}
+#endif /* defined(DEBUG_THREADLOCALS) */
+
+/*!
+ * \brief Retrieve thread storage
+ *
+ * \arg ts This is a pointer to the thread storage structure declared by using
+ * the AST_THREADSTORAGE macro. If declared with
+ * AST_THREADSTORAGE(my_buf, my_buf_init), then this argument would be
+ * (&my_buf).
+ * \arg init_size This is the amount of space to be allocated the first time
+ * this thread requests its data. Thus, this should be the size that the
+ * code accessing this thread storage is assuming the size to be.
+ *
+ * \return This function will return the thread local storage associated with
+ * the thread storage management variable passed as the first argument.
+ * The result will be NULL in the case of a memory allocation error.
+ *
+ * Example usage:
+ * \code
+ * AST_THREADSTORAGE(my_buf, my_buf_init);
+ * #define MY_BUF_SIZE 128
+ * ...
+ * void my_func(const char *fmt, ...)
+ * {
+ * void *buf;
+ *
+ * if (!(buf = ast_threadstorage_get(&my_buf, MY_BUF_SIZE)))
+ * return;
+ * ...
+ * }
+ * \endcode
+ */
+#if !defined(DEBUG_THREADLOCALS)
+AST_INLINE_API(
+void *ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size),
+{
+ void *buf;
+
+ pthread_once(&ts->once, ts->key_init);
+ if (!(buf = pthread_getspecific(ts->key))) {
+ if (!(buf = ast_calloc(1, init_size)))
+ return NULL;
+ if (ts->custom_init && ts->custom_init(buf)) {
+ free(buf);
+ return NULL;
+ }
+ pthread_setspecific(ts->key, buf);
+ }
+
+ return buf;
+}
+)
+#else /* defined(DEBUG_THREADLOCALS) */
+AST_INLINE_API(
+void *__ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size, const char *file, const char *function, unsigned int line),
+{
+ void *buf;
+
+ pthread_once(&ts->once, ts->key_init);
+ if (!(buf = pthread_getspecific(ts->key))) {
+ if (!(buf = ast_calloc(1, init_size)))
+ return NULL;
+ if (ts->custom_init && ts->custom_init(buf)) {
+ free(buf);
+ return NULL;
+ }
+ pthread_setspecific(ts->key, buf);
+ __ast_threadstorage_object_add(buf, init_size, file, function, line);
+ }
+
+ return buf;
+}
+)
+
+#define ast_threadstorage_get(ts, init_size) __ast_threadstorage_get(ts, init_size, __FILE__, __PRETTY_FUNCTION__, __LINE__)
+#endif /* defined(DEBUG_THREADLOCALS) */
+
+#endif /* ASTERISK_THREADSTORAGE_H */
diff --git a/trunk/include/asterisk/time.h b/trunk/include/asterisk/time.h
new file mode 100644
index 000000000..4b7ca00ff
--- /dev/null
+++ b/trunk/include/asterisk/time.h
@@ -0,0 +1,178 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2005, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief Time-related functions and macros
+ */
+
+#ifndef _ASTERISK_TIME_H
+#define _ASTERISK_TIME_H
+
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+
+#include "asterisk/inline_api.h"
+
+/* We have to let the compiler learn what types to use for the elements of a
+ struct timeval since on linux, it's time_t and suseconds_t, but on *BSD,
+ they are just a long. */
+extern struct timeval tv;
+typedef typeof(tv.tv_sec) ast_time_t;
+typedef typeof(tv.tv_usec) ast_suseconds_t;
+
+/*!
+ * \brief Computes the difference (in seconds) between two \c struct \c timeval instances.
+ * \param end the end of the time period
+ * \param start the beginning of the time period
+ * \return the difference in seconds
+ */
+AST_INLINE_API(
+int ast_tvdiff_sec(struct timeval end, struct timeval start),
+{
+ int result = end.tv_sec - start.tv_sec;
+ if (result > 0 && end.tv_usec < start.tv_usec)
+ result--;
+ else if (result < 0 && end.tv_usec > start.tv_usec)
+ result++;
+
+ return result;
+}
+)
+
+/*!
+ * \brief Computes the difference (in microseconds) between two \c struct \c timeval instances.
+ * \param end the end of the time period
+ * \param start the beginning of the time period
+ * \return the difference in microseconds
+ */
+AST_INLINE_API(
+int64_t ast_tvdiff_us(struct timeval end, struct timeval start),
+{
+ return (end.tv_sec - start.tv_sec) * (int64_t) 1000000 +
+ end.tv_usec - start.tv_usec;
+}
+)
+
+/*!
+ * \brief Computes the difference (in milliseconds) between two \c struct \c timeval instances.
+ * \param end end of the time period
+ * \param start beginning of the time period
+ * \return the difference in milliseconds
+ */
+AST_INLINE_API(
+int ast_tvdiff_ms(struct timeval end, struct timeval start),
+{
+ /* the offset by 1,000,000 below is intentional...
+ it avoids differences in the way that division
+ is handled for positive and negative numbers, by ensuring
+ that the divisor is always positive
+ */
+ return ((end.tv_sec - start.tv_sec) * 1000) +
+ (((1000000 + end.tv_usec - start.tv_usec) / 1000) - 1000);
+}
+)
+
+/*!
+ * \brief Returns true if the argument is 0,0
+ */
+AST_INLINE_API(
+int ast_tvzero(const struct timeval t),
+{
+ return (t.tv_sec == 0 && t.tv_usec == 0);
+}
+)
+
+/*!
+ * \brief Compres two \c struct \c timeval instances returning
+ * -1, 0, 1 if the first arg is smaller, equal or greater to the second.
+ */
+AST_INLINE_API(
+int ast_tvcmp(struct timeval _a, struct timeval _b),
+{
+ if (_a.tv_sec < _b.tv_sec)
+ return -1;
+ if (_a.tv_sec > _b.tv_sec)
+ return 1;
+ /* now seconds are equal */
+ if (_a.tv_usec < _b.tv_usec)
+ return -1;
+ if (_a.tv_usec > _b.tv_usec)
+ return 1;
+ return 0;
+}
+)
+
+/*!
+ * \brief Returns true if the two \c struct \c timeval arguments are equal.
+ */
+AST_INLINE_API(
+int ast_tveq(struct timeval _a, struct timeval _b),
+{
+ return (_a.tv_sec == _b.tv_sec && _a.tv_usec == _b.tv_usec);
+}
+)
+
+/*!
+ * \brief Returns current timeval. Meant to replace calls to gettimeofday().
+ */
+AST_INLINE_API(
+struct timeval ast_tvnow(void),
+{
+ struct timeval t;
+ gettimeofday(&t, NULL);
+ return t;
+}
+)
+
+/*!
+ * \brief Returns the sum of two timevals a + b
+ */
+struct timeval ast_tvadd(struct timeval a, struct timeval b);
+
+/*!
+ * \brief Returns the difference of two timevals a - b
+ */
+struct timeval ast_tvsub(struct timeval a, struct timeval b);
+
+/*!
+ * \brief Returns a timeval from sec, usec
+ */
+AST_INLINE_API(
+struct timeval ast_tv(ast_time_t sec, ast_suseconds_t usec),
+{
+ struct timeval t;
+ t.tv_sec = sec;
+ t.tv_usec = usec;
+ return t;
+}
+)
+
+/*!
+ * \brief Returns a timeval corresponding to the duration of n samples at rate r.
+ * Useful to convert samples to timevals, or even milliseconds to timevals
+ * in the form ast_samp2tv(milliseconds, 1000)
+ */
+AST_INLINE_API(
+struct timeval ast_samp2tv(unsigned int _nsamp, unsigned int _rate),
+{
+ return ast_tv(_nsamp / _rate, (_nsamp % _rate) * (1000000 / _rate));
+}
+)
+
+#endif /* _ASTERISK_TIME_H */
diff --git a/trunk/include/asterisk/transcap.h b/trunk/include/asterisk/transcap.h
new file mode 100644
index 000000000..1eca28d6d
--- /dev/null
+++ b/trunk/include/asterisk/transcap.h
@@ -0,0 +1,46 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2005, Digium, Inc.
+ *
+ * Matthew Fredrickson <creslin@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief General Asterisk channel transcoding definitions.
+ */
+
+#ifndef _ASTERISK_TRANSCAP_H
+#define _ASTERISK_TRANSCAP_H
+
+/* These definitions are taken directly out of libpri.h and used here.
+ * DO NOT change them as it will cause unexpected behavior in channels
+ * that utilize these fields.
+ */
+
+/*! \name AstTranscode General Asterisk channel transcoding definitions.
+*/
+/*@{ */
+#define AST_TRANS_CAP_SPEECH 0x0
+#define AST_TRANS_CAP_DIGITAL 0x08
+#define AST_TRANS_CAP_RESTRICTED_DIGITAL 0x09
+#define AST_TRANS_CAP_3_1K_AUDIO 0x10
+#define AST_TRANS_CAP_7K_AUDIO 0x11 /* Depriciated ITU Q.931 (05/1998)*/
+#define AST_TRANS_CAP_DIGITAL_W_TONES 0x11
+#define AST_TRANS_CAP_VIDEO 0x18
+/*@} */
+
+#define IS_DIGITAL(cap)\
+ (cap) & AST_TRANS_CAP_DIGITAL ? 1 : 0
+
+#endif /* _ASTERISK_TRANSCAP_H */
diff --git a/trunk/include/asterisk/translate.h b/trunk/include/asterisk/translate.h
new file mode 100644
index 000000000..97f10283f
--- /dev/null
+++ b/trunk/include/asterisk/translate.h
@@ -0,0 +1,273 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2006, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief Support for translation of data formats.
+ * \ref translate.c
+ */
+
+#ifndef _ASTERISK_TRANSLATE_H
+#define _ASTERISK_TRANSLATE_H
+
+#define MAX_AUDIO_FORMAT 15 /* Do not include video here */
+#define MAX_FORMAT 32 /* Do include video here */
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+#if 1 /* need lots of stuff... */
+#include "asterisk/frame.h"
+#include "asterisk/plc.h"
+#include "asterisk/linkedlists.h"
+// XXX #include "asterisk/module.h"
+#endif
+
+struct ast_trans_pvt; /* declared below */
+
+/*! \brief
+ * Descriptor of a translator.
+ *
+ * Name, callbacks, and various options
+ * related to run-time operation (size of buffers, auxiliary
+ * descriptors, etc).
+ *
+ * A codec registers itself by filling the relevant fields
+ * of a structure and passing it as an argument to
+ * ast_register_translator(). The structure should not be
+ * modified after a successful registration, and its address
+ * must be used as an argument to ast_unregister_translator().
+ *
+ * As a minimum, a translator should supply name, srcfmt and dstfmt,
+ * the required buf_size (in bytes) and buffer_samples (in samples),
+ * and a few callbacks (framein, frameout, sample).
+ * The outbuf is automatically prepended by AST_FRIENDLY_OFFSET
+ * spare bytes so generic routines can place data in there.
+ *
+ * Note, the translator is not supposed to do any memory allocation
+ * or deallocation, nor any locking, because all of this is done in
+ * the generic code.
+ *
+ * Translators using generic plc (packet loss concealment) should
+ * supply a non-zero plc_samples indicating the size (in samples)
+ * of artificially generated frames and incoming data.
+ * Generic plc is only available for dstfmt = SLINEAR
+ */
+struct ast_translator {
+ const char name[80]; /*!< Name of translator */
+ int srcfmt; /*!< Source format (note: bit position,
+ converted to index during registration) */
+ int dstfmt; /*!< Destination format (note: bit position,
+ converted to index during registration) */
+
+ int (*newpvt)(struct ast_trans_pvt *); /*!< initialize private data
+ associated with the translator */
+
+ int (*framein)(struct ast_trans_pvt *pvt, struct ast_frame *in);
+ /*!< Input frame callback. Store
+ (and possibly convert) input frame. */
+
+ struct ast_frame * (*frameout)(struct ast_trans_pvt *pvt);
+ /*!< Output frame callback. Generate a frame
+ with outbuf content. */
+
+ void (*destroy)(struct ast_trans_pvt *pvt);
+ /*!< cleanup private data, if needed
+ (often unnecessary). */
+
+ struct ast_frame * (*sample)(void); /*!< Generate an example frame */
+
+ /*! \brief size of outbuf, in samples. Leave it 0 if you want the framein
+ * callback deal with the frame. Set it appropriately if you
+ * want the code to checks if the incoming frame fits the
+ * outbuf (this is e.g. required for plc).
+ */
+ int buffer_samples; /*< size of outbuf, in samples */
+
+ /*! \brief size of outbuf, in bytes. Mandatory. The wrapper code will also
+ * allocate an AST_FRIENDLY_OFFSET space before.
+ */
+ int buf_size;
+
+ int desc_size; /*!< size of private descriptor in pvt->pvt, if any */
+ int plc_samples; /*!< set to the plc block size if used, 0 otherwise */
+ int useplc; /*!< current status of plc, changed at runtime */
+ int native_plc; /*!< true if the translator can do native plc */
+
+ struct ast_module *module; /* opaque reference to the parent module */
+
+ int cost; /*!< Cost in milliseconds for encoding/decoding 1 second of sound */
+ int active; /*!< Whether this translator should be used or not */
+ AST_LIST_ENTRY(ast_translator) list; /*!< link field */
+};
+
+/*! \brief
+ * Default structure for translators, with the basic fields and buffers,
+ * all allocated as part of the same chunk of memory. The buffer is
+ * preceded by \ref AST_FRIENDLY_OFFSET bytes in front of the user portion.
+ * 'buf' points right after this space.
+ *
+ * *_framein() routines operate in two ways:
+ * 1. some convert on the fly and place the data directly in outbuf;
+ * in this case 'samples' and 'datalen' contain the number of samples
+ * and number of bytes available in the buffer.
+ * In this case we can use a generic *_frameout() routine that simply
+ * takes whatever is there and places it into the output frame.
+ * 2. others simply store the (unconverted) samples into a working
+ * buffer, and leave the conversion task to *_frameout().
+ * In this case, the intermediate buffer must be in the private
+ * descriptor, 'datalen' is left to 0, while 'samples' is still
+ * updated with the number of samples received.
+ */
+struct ast_trans_pvt {
+ struct ast_translator *t;
+ struct ast_frame f; /*!< used in frameout */
+ int samples; /*!< samples available in outbuf */
+ /*! \brief actual space used in outbuf */
+ int datalen;
+ void *pvt; /*!< more private data, if any */
+ char *outbuf; /*!< the useful portion of the buffer */
+ plc_state_t *plc; /*!< optional plc pointer */
+ struct ast_trans_pvt *next; /*!< next in translator chain */
+ struct timeval nextin;
+ struct timeval nextout;
+ unsigned int destroy:1;
+};
+
+/*! \brief generic frameout function */
+struct ast_frame *ast_trans_frameout(struct ast_trans_pvt *pvt,
+ int datalen, int samples);
+
+struct ast_trans_pvt;
+
+/*!
+ * \brief Register a translator
+ * This registers a codec translator with asterisk
+ * \param t populated ast_translator structure
+ * \param module handle to the module that owns this translator
+ * \return 0 on success, -1 on failure
+ */
+int __ast_register_translator(struct ast_translator *t, struct ast_module *module);
+
+/*! \brief See \ref __ast_register_translator() */
+#define ast_register_translator(t) __ast_register_translator(t, ast_module_info->self)
+
+/*!
+ * \brief Unregister a translator
+ * Unregisters the given tranlator
+ * \param t translator to unregister
+ * \return 0 on success, -1 on failure
+ */
+int ast_unregister_translator(struct ast_translator *t);
+
+/*!
+ * \brief Activate a previously deactivated translator
+ * \param t translator to activate
+ * \return nothing
+ *
+ * Enables the specified translator for use.
+ */
+void ast_translator_activate(struct ast_translator *t);
+
+/*!
+ * \brief Deactivate a translator
+ * \param t translator to deactivate
+ * \return nothing
+ *
+ * Disables the specified translator from being used.
+ */
+void ast_translator_deactivate(struct ast_translator *t);
+
+/*!
+ * \brief Chooses the best translation path
+ *
+ * Given a list of sources, and a designed destination format, which should
+ * I choose?
+ * \return Returns 0 on success, -1 if no path could be found.
+ * \note Modifies dests and srcs in place
+ */
+int ast_translator_best_choice(int *dsts, int *srcs);
+
+/*!
+ * \brief Builds a translator path
+ * Build a path (possibly NULL) from source to dest
+ * \param dest destination format
+ * \param source source format
+ * \return ast_trans_pvt on success, NULL on failure
+ * */
+struct ast_trans_pvt *ast_translator_build_path(int dest, int source);
+
+/*!
+ * \brief Frees a translator path
+ * Frees the given translator path structure
+ * \param tr translator path to get rid of
+ */
+void ast_translator_free_path(struct ast_trans_pvt *tr);
+
+/*!
+ * \brief translates one or more frames
+ * Apply an input frame into the translator and receive zero or one output frames. Consume
+ * determines whether the original frame should be freed
+ * \param tr translator structure to use for translation
+ * \param f frame to translate
+ * \param consume Whether or not to free the original frame
+ * \return an ast_frame of the new translation format on success, NULL on failure
+ */
+struct ast_frame *ast_translate(struct ast_trans_pvt *tr, struct ast_frame *f, int consume);
+
+/*!
+ * \brief Returns the number of steps required to convert from 'src' to 'dest'.
+ * \param dest destination format
+ * \param src source format
+ * \return the number of translation steps required, or -1 if no path is available
+ */
+unsigned int ast_translate_path_steps(unsigned int dest, unsigned int src);
+
+/*!
+ * \brief Mask off unavailable formats from a format bitmask
+ * \param dest possible destination formats
+ * \param src source formats
+ * \return the destination formats that are available in the source or translatable
+ *
+ * The result will include all formats from 'dest' that are either present
+ * in 'src' or translatable from a format present in 'src'.
+ *
+ * \note Only a single audio format and a single video format can be
+ * present in 'src', or the function will produce unexpected results.
+ */
+unsigned int ast_translate_available_formats(unsigned int dest, unsigned int src);
+
+/*!
+ * \brief Hint that a frame from a translator has been freed
+ *
+ * This is sort of a hack. This function gets called when ast_frame_free() gets
+ * called on a frame that has the AST_FRFLAG_FROM_TRANSLATOR flag set. This is
+ * because it is possible for a translation path to be destroyed while a frame
+ * from a translator is still in use. Specifically, this happens if a masquerade
+ * happens after a call to ast_read() but before the frame is done being processed,
+ * since the frame processing is generally done without the channel lock held.
+ *
+ * \return nothing
+ */
+void ast_translate_frame_freed(struct ast_frame *fr);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _ASTERISK_TRANSLATE_H */
diff --git a/trunk/include/asterisk/udptl.h b/trunk/include/asterisk/udptl.h
new file mode 100644
index 000000000..74fcf357d
--- /dev/null
+++ b/trunk/include/asterisk/udptl.h
@@ -0,0 +1,127 @@
+/*
+ * Asterisk -- A telephony toolkit for Linux.
+ *
+ * UDPTL support for T.38
+ *
+ * Copyright (C) 2005, Steve Underwood, partly based on RTP code which is
+ * Copyright (C) 1999-2004, Digium, Inc.
+ *
+ * Steve Underwood <steveu@coppice.org>
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License
+ *
+ * A license has been granted to Digium (via disclaimer) for the use of
+ * this code.
+ */
+
+/*! \file
+ * \brief UDPTL support for T.38
+ * \author Steve Underwood <steveu@coppice.org>
+ * \ref udptl.c
+ * \todo add doxygen documentation to this file!
+ */
+
+
+#ifndef _ASTERISK_UDPTL_H
+#define _ASTERISK_UDPTL_H
+
+#include "asterisk/network.h"
+#include "asterisk/frame.h"
+#include "asterisk/io.h"
+#include "asterisk/sched.h"
+#include "asterisk/channel.h"
+
+
+enum {
+ UDPTL_ERROR_CORRECTION_NONE,
+ UDPTL_ERROR_CORRECTION_FEC,
+ UDPTL_ERROR_CORRECTION_REDUNDANCY
+};
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+struct ast_udptl_protocol {
+ /*! \brief Get UDPTL struct, or NULL if unwilling to transfer */
+ struct ast_udptl *(*get_udptl_info)(struct ast_channel *chan);
+ /*! \brief Set UDPTL peer */
+ int (* const set_udptl_peer)(struct ast_channel *chan, struct ast_udptl *peer);
+ const char * const type;
+ AST_RWLIST_ENTRY(ast_udptl_protocol) list;
+};
+
+struct ast_udptl;
+
+typedef int (*ast_udptl_callback)(struct ast_udptl *udptl, struct ast_frame *f, void *data);
+
+struct ast_udptl *ast_udptl_new(struct sched_context *sched, struct io_context *io, int callbackmode);
+
+struct ast_udptl *ast_udptl_new_with_bindaddr(struct sched_context *sched, struct io_context *io, int callbackmode, struct in_addr in);
+
+void ast_udptl_set_peer(struct ast_udptl *udptl, struct sockaddr_in *them);
+
+void ast_udptl_get_peer(struct ast_udptl *udptl, struct sockaddr_in *them);
+
+void ast_udptl_get_us(struct ast_udptl *udptl, struct sockaddr_in *us);
+
+void ast_udptl_destroy(struct ast_udptl *udptl);
+
+void ast_udptl_reset(struct ast_udptl *udptl);
+
+void ast_udptl_set_callback(struct ast_udptl *udptl, ast_udptl_callback callback);
+
+void ast_udptl_set_data(struct ast_udptl *udptl, void *data);
+
+int ast_udptl_write(struct ast_udptl *udptl, struct ast_frame *f);
+
+struct ast_frame *ast_udptl_read(struct ast_udptl *udptl);
+
+int ast_udptl_fd(struct ast_udptl *udptl);
+
+int ast_udptl_setqos(struct ast_udptl *udptl, int tos, int cos);
+
+void ast_udptl_set_m_type(struct ast_udptl* udptl, int pt);
+
+void ast_udptl_set_udptlmap_type(struct ast_udptl* udptl, int pt,
+ char* mimeType, char* mimeSubtype);
+
+int ast_udptl_lookup_code(struct ast_udptl* udptl, int isAstFormat, int code);
+
+void ast_udptl_offered_from_local(struct ast_udptl* udptl, int local);
+
+int ast_udptl_get_error_correction_scheme(struct ast_udptl* udptl);
+
+void ast_udptl_set_error_correction_scheme(struct ast_udptl* udptl, int ec);
+
+int ast_udptl_get_local_max_datagram(struct ast_udptl* udptl);
+
+void ast_udptl_set_local_max_datagram(struct ast_udptl* udptl, int max_datagram);
+
+int ast_udptl_get_far_max_datagram(struct ast_udptl* udptl);
+
+void ast_udptl_set_far_max_datagram(struct ast_udptl* udptl, int max_datagram);
+
+void ast_udptl_get_current_formats(struct ast_udptl* udptl,
+ int* astFormats, int* nonAstFormats);
+
+void ast_udptl_setnat(struct ast_udptl *udptl, int nat);
+
+int ast_udptl_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc);
+
+int ast_udptl_proto_register(struct ast_udptl_protocol *proto);
+
+void ast_udptl_proto_unregister(struct ast_udptl_protocol *proto);
+
+void ast_udptl_stop(struct ast_udptl *udptl);
+
+void ast_udptl_init(void);
+
+void ast_udptl_reload(void);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif
diff --git a/trunk/include/asterisk/ulaw.h b/trunk/include/asterisk/ulaw.h
new file mode 100644
index 000000000..0f3eae58b
--- /dev/null
+++ b/trunk/include/asterisk/ulaw.h
@@ -0,0 +1,87 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2005, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief u-Law to Signed linear conversion
+ */
+
+#ifndef _ASTERISK_ULAW_H
+#define _ASTERISK_ULAW_H
+
+
+/*!
+ * To init the ulaw to slinear conversion stuff, this needs to be run.
+ */
+void ast_ulaw_init(void);
+
+#define AST_ULAW_BIT_LOSS 3
+#define AST_ULAW_STEP (1 << AST_ULAW_BIT_LOSS)
+#define AST_ULAW_TAB_SIZE (32768 / AST_ULAW_STEP + 1)
+#define AST_ULAW_SIGN_BIT 0x80
+
+/*! \brief converts signed linear to mulaw */
+#ifndef G711_NEW_ALGORITHM
+extern unsigned char __ast_lin2mu[16384];
+#else
+extern unsigned char __ast_lin2mu[AST_ULAW_TAB_SIZE];
+#endif
+
+/*! help */
+extern short __ast_mulaw[256];
+
+#ifndef G711_NEW_ALGORITHM
+
+#define AST_LIN2MU(a) (__ast_lin2mu[((unsigned short)(a)) >> 2])
+
+#else
+
+#define AST_LIN2MU_LOOKUP(mag) \
+ __ast_lin2mu[((mag) + AST_ULAW_STEP / 2) >> AST_ULAW_BIT_LOSS]
+
+
+/*! \brief convert signed linear sample to sign-magnitude pair for u-Law */
+static inline void ast_ulaw_get_sign_mag(short sample, unsigned *sign, unsigned *mag)
+{
+ /* It may look illogical to retrive the sign this way in both cases,
+ * but this helps gcc eliminate the branch below and produces
+ * faster code */
+ *sign = ((unsigned short)sample >> 8) & AST_ULAW_SIGN_BIT;
+#if defined(G711_REDUCED_BRANCHING)
+ {
+ unsigned dual_mag = (-sample << 16) | (unsigned short)sample;
+ *mag = (dual_mag >> (*sign >> 3)) & 0xffffU;
+ }
+#else
+ if (sample < 0)
+ *mag = -sample;
+ else
+ *mag = sample;
+#endif /* G711_REDUCED_BRANCHING */
+}
+
+static inline unsigned char AST_LIN2MU(short sample)
+{
+ unsigned mag, sign;
+ ast_ulaw_get_sign_mag(sample, &sign, &mag);
+ return ~(sign | AST_LIN2MU_LOOKUP(mag));
+}
+#endif
+
+#define AST_MULAW(a) (__ast_mulaw[(a)])
+
+#endif /* _ASTERISK_ULAW_H */
diff --git a/trunk/include/asterisk/unaligned.h b/trunk/include/asterisk/unaligned.h
new file mode 100644
index 000000000..c502efede
--- /dev/null
+++ b/trunk/include/asterisk/unaligned.h
@@ -0,0 +1,102 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2005, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief Handle unaligned data access
+ */
+
+#ifndef _ASTERISK_UNALIGNED_H
+#define _ASTERISK_UNALIGNED_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+#ifdef __GNUC__
+/* If we just tell GCC what's going on, we can trust it to behave optimally */
+static inline unsigned int get_unaligned_uint32(const void *p)
+{
+ const struct { unsigned int d; } __attribute__((packed)) *pp = p;
+
+ return pp->d;
+}
+static inline unsigned short get_unaligned_uint16(const void *p)
+{
+ const struct { unsigned short d; } __attribute__((packed)) *pp = p;
+
+ return pp->d;
+}
+
+static inline void put_unaligned_uint32(void *p, unsigned int datum)
+{
+ struct { unsigned int d; } __attribute__((packed)) *pp = p;
+
+ pp->d = datum;
+}
+
+static inline void put_unaligned_uint16(void *p, unsigned short datum)
+{
+ struct { unsigned short d; } __attribute__((packed)) *pp = p;
+
+ pp->d = datum;
+}
+#elif defined(SOLARIS) && defined(__sparc__)
+static inline unsigned int get_unaligned_uint32(const void *p)
+{
+ const unsigned char *cp = p;
+
+ return (cp[0] << 24) | (cp[1] << 16) | (cp[2] << 8) | cp[3];
+}
+
+static inline unsigned short get_unaligned_uint16(const void *p)
+{
+ const unsigned char *cp = p;
+
+ return (cp[0] << 8) | cp[1] ;
+}
+
+static inline void put_unaligned_uint32(void *p, unsigned int datum)
+{
+ unsigned char *cp = p;
+
+ cp[0] = datum >> 24;
+ cp[1] = datum >> 16;
+ cp[2] = datum >> 8;
+ cp[3] = datum;
+}
+
+static inline void put_unaligned_uint16(void *p, unsigned int datum)
+{
+ unsigned char *cp = p;
+
+ cp[0] = datum >> 8;
+ cp[1] = datum;
+}
+#else /* Not GCC, not Solaris/SPARC. Assume we can handle direct load/store. */
+#define get_unaligned_uint32(p) (*((unsigned int *)(p)))
+#define get_unaligned_uint16(p) (*((unsigned short *)(p)))
+#define put_unaligned_uint32(p,d) do { unsigned int *__P = (p); *__P = d; } while(0)
+#define put_unaligned_uint16(p,d) do { unsigned short *__P = (p); *__P = d; } while(0)
+#endif
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+
+#endif /* _ASTERISK_UNALIGNED_H */
diff --git a/trunk/include/asterisk/utils.h b/trunk/include/asterisk/utils.h
new file mode 100644
index 000000000..a9c8d5f0c
--- /dev/null
+++ b/trunk/include/asterisk/utils.h
@@ -0,0 +1,657 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2006, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ * \brief Utility functions
+ */
+
+#ifndef _ASTERISK_UTILS_H
+#define _ASTERISK_UTILS_H
+
+#include "asterisk/network.h"
+
+#include <time.h> /* we want to override localtime_r */
+
+#include "asterisk/lock.h"
+#include "asterisk/time.h"
+#include "asterisk/logger.h"
+#include "asterisk/localtime.h"
+
+/*!
+\note \verbatim
+ Note:
+ It is very important to use only unsigned variables to hold
+ bit flags, as otherwise you can fall prey to the compiler's
+ sign-extension antics if you try to use the top two bits in
+ your variable.
+
+ The flag macros below use a set of compiler tricks to verify
+ that the caller is using an "unsigned int" variable to hold
+ the flags, and nothing else. If the caller uses any other
+ type of variable, a warning message similar to this:
+
+ warning: comparison of distinct pointer types lacks cast
+ will be generated.
+
+ The "dummy" variable below is used to make these comparisons.
+
+ Also note that at -O2 or above, this type-safety checking
+ does _not_ produce any additional object code at all.
+ \endverbatim
+*/
+
+extern unsigned int __unsigned_int_flags_dummy;
+
+#define ast_test_flag(p,flag) ({ \
+ typeof ((p)->flags) __p = (p)->flags; \
+ typeof (__unsigned_int_flags_dummy) __x = 0; \
+ (void) (&__p == &__x); \
+ ((p)->flags & (flag)); \
+ })
+
+#define ast_set_flag(p,flag) do { \
+ typeof ((p)->flags) __p = (p)->flags; \
+ typeof (__unsigned_int_flags_dummy) __x = 0; \
+ (void) (&__p == &__x); \
+ ((p)->flags |= (flag)); \
+ } while(0)
+
+#define ast_clear_flag(p,flag) do { \
+ typeof ((p)->flags) __p = (p)->flags; \
+ typeof (__unsigned_int_flags_dummy) __x = 0; \
+ (void) (&__p == &__x); \
+ ((p)->flags &= ~(flag)); \
+ } while(0)
+
+#define ast_copy_flags(dest,src,flagz) do { \
+ typeof ((dest)->flags) __d = (dest)->flags; \
+ typeof ((src)->flags) __s = (src)->flags; \
+ typeof (__unsigned_int_flags_dummy) __x = 0; \
+ (void) (&__d == &__x); \
+ (void) (&__s == &__x); \
+ (dest)->flags &= ~(flagz); \
+ (dest)->flags |= ((src)->flags & (flagz)); \
+ } while (0)
+
+#define ast_set2_flag(p,value,flag) do { \
+ typeof ((p)->flags) __p = (p)->flags; \
+ typeof (__unsigned_int_flags_dummy) __x = 0; \
+ (void) (&__p == &__x); \
+ if (value) \
+ (p)->flags |= (flag); \
+ else \
+ (p)->flags &= ~(flag); \
+ } while (0)
+
+#define ast_set_flags_to(p,flag,value) do { \
+ typeof ((p)->flags) __p = (p)->flags; \
+ typeof (__unsigned_int_flags_dummy) __x = 0; \
+ (void) (&__p == &__x); \
+ (p)->flags &= ~(flag); \
+ (p)->flags |= (value); \
+ } while (0)
+
+
+/* The following 64-bit flag code can most likely be erased after app_dial
+ is reorganized to either reduce the large number of options, or handle
+ them in some other way. At the time of this writing, app_dial would be
+ the only user of 64-bit option flags */
+
+extern uint64_t __unsigned_int_flags_dummy64;
+
+#define ast_test_flag64(p,flag) ({ \
+ typeof ((p)->flags) __p = (p)->flags; \
+ typeof (__unsigned_int_flags_dummy64) __x = 0; \
+ (void) (&__p == &__x); \
+ ((p)->flags & (flag)); \
+ })
+
+#define ast_set_flag64(p,flag) do { \
+ typeof ((p)->flags) __p = (p)->flags; \
+ typeof (__unsigned_int_flags_dummy64) __x = 0; \
+ (void) (&__p == &__x); \
+ ((p)->flags |= (flag)); \
+ } while(0)
+
+#define ast_clear_flag64(p,flag) do { \
+ typeof ((p)->flags) __p = (p)->flags; \
+ typeof (__unsigned_int_flags_dummy64) __x = 0; \
+ (void) (&__p == &__x); \
+ ((p)->flags &= ~(flag)); \
+ } while(0)
+
+#define ast_copy_flags64(dest,src,flagz) do { \
+ typeof ((dest)->flags) __d = (dest)->flags; \
+ typeof ((src)->flags) __s = (src)->flags; \
+ typeof (__unsigned_int_flags_dummy64) __x = 0; \
+ (void) (&__d == &__x); \
+ (void) (&__s == &__x); \
+ (dest)->flags &= ~(flagz); \
+ (dest)->flags |= ((src)->flags & (flagz)); \
+ } while (0)
+
+#define ast_set2_flag64(p,value,flag) do { \
+ typeof ((p)->flags) __p = (p)->flags; \
+ typeof (__unsigned_int_flags_dummy64) __x = 0; \
+ (void) (&__p == &__x); \
+ if (value) \
+ (p)->flags |= (flag); \
+ else \
+ (p)->flags &= ~(flag); \
+ } while (0)
+
+#define ast_set_flags_to64(p,flag,value) do { \
+ typeof ((p)->flags) __p = (p)->flags; \
+ typeof (__unsigned_int_flags_dummy64) __x = 0; \
+ (void) (&__p == &__x); \
+ (p)->flags &= ~(flag); \
+ (p)->flags |= (value); \
+ } while (0)
+
+
+/* Non-type checking variations for non-unsigned int flags. You
+ should only use non-unsigned int flags where required by
+ protocol etc and if you know what you're doing :) */
+#define ast_test_flag_nonstd(p,flag) \
+ ((p)->flags & (flag))
+
+#define ast_set_flag_nonstd(p,flag) do { \
+ ((p)->flags |= (flag)); \
+ } while(0)
+
+#define ast_clear_flag_nonstd(p,flag) do { \
+ ((p)->flags &= ~(flag)); \
+ } while(0)
+
+#define ast_copy_flags_nonstd(dest,src,flagz) do { \
+ (dest)->flags &= ~(flagz); \
+ (dest)->flags |= ((src)->flags & (flagz)); \
+ } while (0)
+
+#define ast_set2_flag_nonstd(p,value,flag) do { \
+ if (value) \
+ (p)->flags |= (flag); \
+ else \
+ (p)->flags &= ~(flag); \
+ } while (0)
+
+#define AST_FLAGS_ALL UINT_MAX
+
+/*! \brief Structure used to handle boolean flags
+*/
+struct ast_flags {
+ unsigned int flags;
+};
+
+/*! \brief Structure used to handle a large number of boolean flags == used only in app_dial?
+*/
+struct ast_flags64 {
+ uint64_t flags;
+};
+
+struct ast_hostent {
+ struct hostent hp;
+ char buf[1024];
+};
+
+/*! \brief Thread-safe gethostbyname function to use in Asterisk */
+struct hostent *ast_gethostbyname(const char *host, struct ast_hostent *hp);
+
+/*! \brief Produces MD5 hash based on input string */
+void ast_md5_hash(char *output, char *input);
+/*! \brief Produces SHA1 hash based on input string */
+void ast_sha1_hash(char *output, char *input);
+
+int ast_base64encode_full(char *dst, const unsigned char *src, int srclen, int max, int linebreaks);
+
+/*!
+ * \brief Encode data in base64
+ * \param dst the destination buffer
+ * \param src the source data to be encoded
+ * \param srclen the number of bytes present in the source buffer
+ * \param max the maximum number of bytes to write into the destination
+ * buffer, *including* the terminating NULL character.
+ */
+int ast_base64encode(char *dst, const unsigned char *src, int srclen, int max);
+
+/*!
+ * \brief Decode data from base64
+ * \param dst the destination buffer
+ * \param src the source buffer
+ * \param max The maximum number of bytes to write into the destination
+ * buffer. Note that this function will not ensure that the
+ * destination buffer is NULL terminated. So, in general,
+ * this parameter should be sizeof(dst) - 1.
+ */
+int ast_base64decode(unsigned char *dst, const char *src, int max);
+
+/*! \brief Turn text string to URI-encoded %XX version
+
+\note At this point, we're converting from ISO-8859-x (8-bit), not UTF8
+ as in the SIP protocol spec
+ If doreserved == 1 we will convert reserved characters also.
+ RFC 2396, section 2.4
+ outbuf needs to have more memory allocated than the instring
+ to have room for the expansion. Every char that is converted
+ is replaced by three ASCII characters.
+ \param string String to be converted
+ \param outbuf Resulting encoded string
+ \param buflen Size of output buffer
+ \param doreserved Convert reserved characters
+*/
+
+char *ast_uri_encode(const char *string, char *outbuf, int buflen, int doreserved);
+
+/*! \brief Decode URI, URN, URL (overwrite string)
+ \param s String to be decoded
+ */
+void ast_uri_decode(char *s);
+
+static force_inline void ast_slinear_saturated_add(short *input, short *value)
+{
+ int res;
+
+ res = (int) *input + *value;
+ if (res > 32767)
+ *input = 32767;
+ else if (res < -32767)
+ *input = -32767;
+ else
+ *input = (short) res;
+}
+
+static force_inline void ast_slinear_saturated_subtract(short *input, short *value)
+{
+ int res;
+
+ res = (int) *input - *value;
+ if (res > 32767)
+ *input = 32767;
+ else if (res < -32767)
+ *input = -32767;
+ else
+ *input = (short) res;
+}
+
+static force_inline void ast_slinear_saturated_multiply(short *input, short *value)
+{
+ int res;
+
+ res = (int) *input * *value;
+ if (res > 32767)
+ *input = 32767;
+ else if (res < -32767)
+ *input = -32767;
+ else
+ *input = (short) res;
+}
+
+static force_inline void ast_slinear_saturated_divide(short *input, short *value)
+{
+ *input /= *value;
+}
+
+int test_for_thread_safety(void);
+
+#ifdef localtime_r
+#undef localtime_r
+#endif
+#define localtime_r __dont_use_localtime_r_use_ast_localtime_instead__
+
+int ast_utils_init(void);
+int ast_wait_for_input(int fd, int ms);
+
+/*!
+ \brief Try to write string, but wait no more than ms milliseconds
+ before timing out.
+
+ \note If you are calling ast_carefulwrite, it is assumed that you are calling
+ it on a file descriptor that _DOES_ have NONBLOCK set. This way,
+ there is only one system call made to do a write, unless we actually
+ have a need to wait. This way, we get better performance.
+*/
+int ast_carefulwrite(int fd, char *s, int len, int timeoutms);
+
+/*
+ * Thread management support (should be moved to lock.h or a different header)
+ */
+
+#define AST_STACKSIZE 240 * 1024
+
+#if defined(LOW_MEMORY)
+#define AST_BACKGROUND_STACKSIZE 48 * 1024
+#else
+#define AST_BACKGROUND_STACKSIZE 240 * 1024
+#endif
+
+void ast_register_thread(char *name);
+void ast_unregister_thread(void *id);
+
+int ast_pthread_create_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *),
+ void *data, size_t stacksize, const char *file, const char *caller,
+ int line, const char *start_fn);
+
+int ast_pthread_create_detached_stack(pthread_t *thread, pthread_attr_t *attr, void*(*start_routine)(void *),
+ void *data, size_t stacksize, const char *file, const char *caller,
+ int line, const char *start_fn);
+
+#define ast_pthread_create(a, b, c, d) \
+ ast_pthread_create_stack(a, b, c, d, \
+ 0, __FILE__, __FUNCTION__, __LINE__, #c)
+
+#define ast_pthread_create_detached(a, b, c, d) \
+ ast_pthread_create_detached_stack(a, b, c, d, \
+ 0, __FILE__, __FUNCTION__, __LINE__, #c)
+
+#define ast_pthread_create_background(a, b, c, d) \
+ ast_pthread_create_stack(a, b, c, d, \
+ AST_BACKGROUND_STACKSIZE, \
+ __FILE__, __FUNCTION__, __LINE__, #c)
+
+#define ast_pthread_create_detached_background(a, b, c, d) \
+ ast_pthread_create_detached_stack(a, b, c, d, \
+ AST_BACKGROUND_STACKSIZE, \
+ __FILE__, __FUNCTION__, __LINE__, #c)
+
+/* End of thread management support */
+
+/*!
+ \brief Process a string to find and replace characters
+ \param start The string to analyze
+ \param find The character to find
+ \param replace_with The character that will replace the one we are looking for
+*/
+char *ast_process_quotes_and_slashes(char *start, char find, char replace_with);
+
+long int ast_random(void);
+
+#define ast_free free
+
+/*!
+ * \brief free() wrapper
+ *
+ * ast_free_ptr should be used when a function pointer for free() needs to be passed
+ * as the argument to a function. Otherwise, astmm will cause seg faults.
+ */
+#ifdef __AST_DEBUG_MALLOC
+static void ast_free_ptr(void *ptr) attribute_unused;
+static void ast_free_ptr(void *ptr)
+{
+ ast_free(ptr);
+}
+#else
+#define ast_free_ptr ast_free
+#endif
+
+#ifndef __AST_DEBUG_MALLOC
+
+#define MALLOC_FAILURE_MSG \
+ ast_log(LOG_ERROR, "Memory Allocation Failure in function %s at line %d of %s\n", func, lineno, file);
+/*!
+ * \brief A wrapper for malloc()
+ *
+ * ast_malloc() is a wrapper for malloc() that will generate an Asterisk log
+ * message in the case that the allocation fails.
+ *
+ * The argument and return value are the same as malloc()
+ */
+#define ast_malloc(len) \
+ _ast_malloc((len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
+
+AST_INLINE_API(
+void * attribute_malloc _ast_malloc(size_t len, const char *file, int lineno, const char *func),
+{
+ void *p;
+
+ if (!(p = malloc(len)))
+ MALLOC_FAILURE_MSG;
+
+ return p;
+}
+)
+
+/*!
+ * \brief A wrapper for calloc()
+ *
+ * ast_calloc() is a wrapper for calloc() that will generate an Asterisk log
+ * message in the case that the allocation fails.
+ *
+ * The arguments and return value are the same as calloc()
+ */
+#define ast_calloc(num, len) \
+ _ast_calloc((num), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
+
+AST_INLINE_API(
+void * attribute_malloc _ast_calloc(size_t num, size_t len, const char *file, int lineno, const char *func),
+{
+ void *p;
+
+ if (!(p = calloc(num, len)))
+ MALLOC_FAILURE_MSG;
+
+ return p;
+}
+)
+
+/*!
+ * \brief A wrapper for calloc() for use in cache pools
+ *
+ * ast_calloc_cache() is a wrapper for calloc() that will generate an Asterisk log
+ * message in the case that the allocation fails. When memory debugging is in use,
+ * the memory allocated by this function will be marked as 'cache' so it can be
+ * distinguished from normal memory allocations.
+ *
+ * The arguments and return value are the same as calloc()
+ */
+#define ast_calloc_cache(num, len) \
+ _ast_calloc((num), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
+
+/*!
+ * \brief A wrapper for realloc()
+ *
+ * ast_realloc() is a wrapper for realloc() that will generate an Asterisk log
+ * message in the case that the allocation fails.
+ *
+ * The arguments and return value are the same as realloc()
+ */
+#define ast_realloc(p, len) \
+ _ast_realloc((p), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
+
+AST_INLINE_API(
+void * attribute_malloc _ast_realloc(void *p, size_t len, const char *file, int lineno, const char *func),
+{
+ void *newp;
+
+ if (!(newp = realloc(p, len)))
+ MALLOC_FAILURE_MSG;
+
+ return newp;
+}
+)
+
+/*!
+ * \brief A wrapper for strdup()
+ *
+ * ast_strdup() is a wrapper for strdup() that will generate an Asterisk log
+ * message in the case that the allocation fails.
+ *
+ * ast_strdup(), unlike strdup(), can safely accept a NULL argument. If a NULL
+ * argument is provided, ast_strdup will return NULL without generating any
+ * kind of error log message.
+ *
+ * The argument and return value are the same as strdup()
+ */
+#define ast_strdup(str) \
+ _ast_strdup((str), __FILE__, __LINE__, __PRETTY_FUNCTION__)
+
+AST_INLINE_API(
+char * attribute_malloc _ast_strdup(const char *str, const char *file, int lineno, const char *func),
+{
+ char *newstr = NULL;
+
+ if (str) {
+ if (!(newstr = strdup(str)))
+ MALLOC_FAILURE_MSG;
+ }
+
+ return newstr;
+}
+)
+
+/*!
+ * \brief A wrapper for strndup()
+ *
+ * ast_strndup() is a wrapper for strndup() that will generate an Asterisk log
+ * message in the case that the allocation fails.
+ *
+ * ast_strndup(), unlike strndup(), can safely accept a NULL argument for the
+ * string to duplicate. If a NULL argument is provided, ast_strdup will return
+ * NULL without generating any kind of error log message.
+ *
+ * The arguments and return value are the same as strndup()
+ */
+#define ast_strndup(str, len) \
+ _ast_strndup((str), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)
+
+AST_INLINE_API(
+char * attribute_malloc _ast_strndup(const char *str, size_t len, const char *file, int lineno, const char *func),
+{
+ char *newstr = NULL;
+
+ if (str) {
+ if (!(newstr = strndup(str, len)))
+ MALLOC_FAILURE_MSG;
+ }
+
+ return newstr;
+}
+)
+
+/*!
+ * \brief A wrapper for asprintf()
+ *
+ * ast_asprintf() is a wrapper for asprintf() that will generate an Asterisk log
+ * message in the case that the allocation fails.
+ *
+ * The arguments and return value are the same as asprintf()
+ */
+#define ast_asprintf(ret, fmt, ...) \
+ _ast_asprintf((ret), __FILE__, __LINE__, __PRETTY_FUNCTION__, fmt, __VA_ARGS__)
+
+AST_INLINE_API(
+int _ast_asprintf(char **ret, const char *file, int lineno, const char *func, const char *fmt, ...),
+{
+ int res;
+ va_list ap;
+
+ va_start(ap, fmt);
+ if ((res = vasprintf(ret, fmt, ap)) == -1)
+ MALLOC_FAILURE_MSG;
+ va_end(ap);
+
+ return res;
+}
+)
+
+/*!
+ * \brief A wrapper for vasprintf()
+ *
+ * ast_vasprintf() is a wrapper for vasprintf() that will generate an Asterisk log
+ * message in the case that the allocation fails.
+ *
+ * The arguments and return value are the same as vasprintf()
+ */
+#define ast_vasprintf(ret, fmt, ap) \
+ _ast_vasprintf((ret), __FILE__, __LINE__, __PRETTY_FUNCTION__, (fmt), (ap))
+
+AST_INLINE_API(
+int _ast_vasprintf(char **ret, const char *file, int lineno, const char *func, const char *fmt, va_list ap),
+{
+ int res;
+
+ if ((res = vasprintf(ret, fmt, ap)) == -1)
+ MALLOC_FAILURE_MSG;
+
+ return res;
+}
+)
+
+#else
+
+/* If astmm is in use, let it handle these. Otherwise, it will report that
+ all allocations are coming from this header file */
+
+#define ast_malloc(a) malloc(a)
+#define ast_calloc(a,b) calloc(a,b)
+#define ast_realloc(a,b) realloc(a,b)
+#define ast_strdup(a) strdup(a)
+#define ast_strndup(a,b) strndup(a,b)
+#define ast_asprintf(a,b,c) asprintf(a,b,c)
+#define ast_vasprintf(a,b,c) vasprintf(a,b,c)
+
+#endif /* AST_DEBUG_MALLOC */
+
+#if !defined(ast_strdupa) && defined(__GNUC__)
+/*!
+ \brief duplicate a string in memory from the stack
+ \param s The string to duplicate
+
+ This macro will duplicate the given string. It returns a pointer to the stack
+ allocatted memory for the new string.
+*/
+#define ast_strdupa(s) \
+ (__extension__ \
+ ({ \
+ const char *__old = (s); \
+ size_t __len = strlen(__old) + 1; \
+ char *__new = __builtin_alloca(__len); \
+ memcpy (__new, __old, __len); \
+ __new; \
+ }))
+#endif
+
+/*!
+ \brief Disable PMTU discovery on a socket
+ \param sock The socket to manipulate
+ \return Nothing
+
+ On Linux, UDP sockets default to sending packets with the Dont Fragment (DF)
+ bit set. This is supposedly done to allow the application to do PMTU
+ discovery, but Asterisk does not do this.
+
+ Because of this, UDP packets sent by Asterisk that are larger than the MTU
+ of any hop in the path will be lost. This function can be called on a socket
+ to ensure that the DF bit will not be set.
+ */
+void ast_enable_packet_fragmentation(int sock);
+
+/*!
+ \brief Recursively create directory path
+ \param path The directory path to create
+ \param mode The permissions with which to try to create the directory
+ \return 0 on success or an error code otherwise
+
+ Creates a directory path, creating parent directories as needed.
+ */
+int ast_mkdir(const char *path, int mode);
+
+#define ARRAY_LEN(a) (sizeof(a) / sizeof(a[0]))
+
+#include "asterisk/strings.h"
+
+#endif /* _ASTERISK_UTILS_H */
diff --git a/trunk/include/asterisk/version.h b/trunk/include/asterisk/version.h
new file mode 100644
index 000000000..51ff48102
--- /dev/null
+++ b/trunk/include/asterisk/version.h
@@ -0,0 +1,44 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2008, Digium, Inc.
+ *
+ * Russell Bryant <russell@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*!
+ * \file
+ * \brief Asterisk version information
+ * \author Russell Bryant <russell@digium.com>
+ */
+
+#ifndef __AST_VERSION_H
+#define __AST_VERSION_H
+
+/*!
+ * \brief Retrieve the Asterisk version string.
+ */
+const char *ast_get_version(void);
+
+/*!
+ * \brief Retrieve the numeric Asterisk version
+ *
+ * Format ABBCC
+ * AABB - Major version (1.4 would be 104)
+ * CC - Minor version
+ *
+ * 1.4.17 would be 10417.
+ */
+const char *ast_get_version_num(void);
+
+#endif /* __AST_VERSION_H */
diff --git a/trunk/include/asterisk/zapata.h b/trunk/include/asterisk/zapata.h
new file mode 100644
index 000000000..50df73a58
--- /dev/null
+++ b/trunk/include/asterisk/zapata.h
@@ -0,0 +1,48 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2007, Digium, Inc.
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ *
+ * Sometimes one really wonders why we need a copyright
+ * for less than ten lines of preprocessor directives...
+ */
+
+/*! \file
+ * \brief Stub to find zaptel headers
+*
+ * Stub to find the zaptel headers. The configure script will
+ * define HAVE_ZAPTEL_VERSION according to what it has found.
+ * Applications should include "zapata.h" and not (directly)
+ * <foo/zaptel.h> or <foo/tonezone.h>.
+ * For the mapping of version numbers to location see below.
+ *
+ */
+#ifndef _AST_ZAPATA_H
+#define _AST_ZAPATA_H
+
+#ifdef HAVE_ZAPTEL
+#include <sys/ioctl.h>
+
+#if defined(HAVE_ZAPTEL_VERSION) && HAVE_ZAPTEL_VERSION < 100
+/* Very old versions of zaptel drivers on FreeBSD install in ${PREFIX} */
+#include <zaptel.h>
+#include <tonezone.h>
+#else
+/* newer versions install in ${PREFIX}/zaptel */
+#include <zaptel/zaptel.h>
+#include <zaptel/tonezone.h>
+#endif /* HAVE_ZAPTEL_VERSION < 100 */
+
+#endif /* HAVE_ZAPTEL */
+
+#endif /* _AST_ZAPATA_H */