aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/asterisk.h210
-rw-r--r--include/asterisk/abstract_jb.h226
-rw-r--r--include/asterisk/acl.h57
-rw-r--r--include/asterisk/adsi.h353
-rw-r--r--include/asterisk/ael_structs.h195
-rw-r--r--include/asterisk/aes.h170
-rw-r--r--include/asterisk/agi.h57
-rw-r--r--include/asterisk/alaw.h43
-rw-r--r--include/asterisk/app.h434
-rw-r--r--include/asterisk/ast_expr.h32
-rw-r--r--include/asterisk/astdb.h52
-rw-r--r--include/asterisk/astmm.h89
-rw-r--r--include/asterisk/astobj.h824
-rw-r--r--include/asterisk/astobj2.h560
-rw-r--r--include/asterisk/astosp.h31
-rw-r--r--include/asterisk/audiohook.h211
-rw-r--r--include/asterisk/autoconfig.h.in713
-rw-r--r--include/asterisk/callerid.h339
-rw-r--r--include/asterisk/causes.h83
-rw-r--r--include/asterisk/cdr.h342
-rw-r--r--include/asterisk/channel.h1442
-rw-r--r--include/asterisk/chanvars.h42
-rw-r--r--include/asterisk/cli.h183
-rw-r--r--include/asterisk/compat.h131
-rw-r--r--include/asterisk/compiler.h62
-rw-r--r--include/asterisk/config.h206
-rw-r--r--include/asterisk/crypto.h112
-rw-r--r--include/asterisk/dahdi_compat.h458
-rw-r--r--include/asterisk/devicestate.h133
-rw-r--r--include/asterisk/dial.h151
-rw-r--r--include/asterisk/dns.h39
-rw-r--r--include/asterisk/dnsmgr.h62
-rw-r--r--include/asterisk/doxyref.h580
-rw-r--r--include/asterisk/dsp.h124
-rw-r--r--include/asterisk/dundi.h226
-rw-r--r--include/asterisk/endian.h62
-rw-r--r--include/asterisk/enum.h59
-rw-r--r--include/asterisk/features.h101
-rw-r--r--include/asterisk/file.h434
-rw-r--r--include/asterisk/frame.h597
-rw-r--r--include/asterisk/fskmodem.h72
-rw-r--r--include/asterisk/global_datastores.h47
-rw-r--r--include/asterisk/http.h65
-rw-r--r--include/asterisk/image.h96
-rw-r--r--include/asterisk/indications.h89
-rw-r--r--include/asterisk/inline_api.h66
-rw-r--r--include/asterisk/io.h145
-rw-r--r--include/asterisk/jabber.h146
-rw-r--r--include/asterisk/jingle.h45
-rw-r--r--include/asterisk/linkedlists.h761
-rw-r--r--include/asterisk/localtime.h30
-rw-r--r--include/asterisk/lock.h1253
-rw-r--r--include/asterisk/logger.h139
-rw-r--r--include/asterisk/manager.h148
-rw-r--r--include/asterisk/md5.h40
-rw-r--r--include/asterisk/module.h292
-rw-r--r--include/asterisk/monitor.h66
-rw-r--r--include/asterisk/musiconhold.h59
-rw-r--r--include/asterisk/netsock.h68
-rw-r--r--include/asterisk/options.h138
-rw-r--r--include/asterisk/paths.h43
-rw-r--r--include/asterisk/pbx.h915
-rw-r--r--include/asterisk/plc.h161
-rw-r--r--include/asterisk/poll-compat.h111
-rw-r--r--include/asterisk/privacy.h46
-rw-r--r--include/asterisk/res_odbc.h103
-rw-r--r--include/asterisk/rtp.h265
-rw-r--r--include/asterisk/say.h158
-rw-r--r--include/asterisk/sched.h198
-rw-r--r--include/asterisk/sha1.h81
-rw-r--r--include/asterisk/slinfactory.h57
-rw-r--r--include/asterisk/smdi.h195
-rw-r--r--include/asterisk/speech.h152
-rw-r--r--include/asterisk/srv.h45
-rw-r--r--include/asterisk/stringfields.h391
-rw-r--r--include/asterisk/strings.h304
-rw-r--r--include/asterisk/tdd.h82
-rw-r--r--include/asterisk/term.h76
-rw-r--r--include/asterisk/threadstorage.h498
-rw-r--r--include/asterisk/time.h144
-rw-r--r--include/asterisk/tonezone_compat.h35
-rw-r--r--include/asterisk/transcap.h42
-rw-r--r--include/asterisk/translate.h273
-rw-r--r--include/asterisk/udptl.h120
-rw-r--r--include/asterisk/ulaw.h43
-rw-r--r--include/asterisk/unaligned.h102
-rw-r--r--include/asterisk/utils.h578
-rw-r--r--include/jitterbuf.h162
-rw-r--r--include/solaris-compat/compat.h46
-rw-r--r--include/solaris-compat/sys/cdefs.h10
-rw-r--r--include/solaris-compat/sys/queue.h540
91 files changed, 19966 insertions, 0 deletions
diff --git a/include/asterisk.h b/include/asterisk.h
new file mode 100644
index 000000000..20f5aa9d4
--- /dev/null
+++ b/include/asterisk.h
@@ -0,0 +1,210 @@
+/*
+ * Asterisk -- A telephony toolkit for Linux.
+ *
+ * General Definitions for Asterisk top level program
+ *
+ * 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 main include file. File version handling, generic pbx functions.
+ */
+
+#ifndef _ASTERISK_H
+#define _ASTERISK_H
+
+#include "asterisk/autoconfig.h"
+
+#if !defined(NO_MALLOC_DEBUG) && !defined(STANDALONE_AEL) && defined(MALLOC_DEBUG)
+#include "asterisk/astmm.h"
+#endif
+
+#include "asterisk/compat.h"
+
+#include "asterisk/paths.h"
+
+#define DEFAULT_LANGUAGE "en"
+
+#define DEFAULT_SAMPLE_RATE 8000
+#define DEFAULT_SAMPLES_PER_MS ((DEFAULT_SAMPLE_RATE)/1000)
+#define setpriority __PLEASE_USE_ast_set_priority_INSTEAD_OF_setpriority__
+#define sched_setscheduler __PLEASE_USE_ast_set_priority_INSTEAD_OF_sched_setscheduler__
+
+/* provided in asterisk.c */
+extern char ast_config_AST_CONFIG_DIR[PATH_MAX];
+extern char ast_config_AST_CONFIG_FILE[PATH_MAX];
+extern char ast_config_AST_MODULE_DIR[PATH_MAX];
+extern char ast_config_AST_SPOOL_DIR[PATH_MAX];
+extern char ast_config_AST_MONITOR_DIR[PATH_MAX];
+extern char ast_config_AST_VAR_DIR[PATH_MAX];
+extern char ast_config_AST_DATA_DIR[PATH_MAX];
+extern char ast_config_AST_LOG_DIR[PATH_MAX];
+extern char ast_config_AST_AGI_DIR[PATH_MAX];
+extern char ast_config_AST_DB[PATH_MAX];
+extern char ast_config_AST_KEY_DIR[PATH_MAX];
+extern char ast_config_AST_PID[PATH_MAX];
+extern char ast_config_AST_SOCKET[PATH_MAX];
+extern char ast_config_AST_RUN_DIR[PATH_MAX];
+extern char ast_config_AST_CTL_PERMISSIONS[PATH_MAX];
+extern char ast_config_AST_CTL_OWNER[PATH_MAX];
+extern char ast_config_AST_CTL_GROUP[PATH_MAX];
+extern char ast_config_AST_CTL[PATH_MAX];
+extern char ast_config_AST_SYSTEM_NAME[20];
+
+int ast_set_priority(int); /*!< Provided by asterisk.c */
+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 reload_logger(int); /*!< 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 */
+int astobj2_init(void); /*! Provided by astobj2.c */
+void ast_autoservice_init(void); /*!< Provided by autoservice.c */
+
+/* Many headers need 'ast_channel' to be defined */
+struct ast_channel;
+
+/* Many headers need 'ast_module' to be defined */
+struct ast_module;
+
+/*!
+ * \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 Zero if the specified module was not found, 1 if the module was
+ * found but cannot be reloaded, -1 if a reload operation is already in
+ * progress, and 2 if the specfied module was found and reloaded.
+ */
+int ast_module_reload(const char *name);
+
+/*!
+ * \brief Register a function to be executed before Asterisk exits.
+ * \param func The callback function to use.
+ *
+ * \return Zero on success, -1 on error.
+ */
+int ast_register_atexit(void (*func)(void));
+
+/*!
+ * \brief Unregister a function registered with ast_register_atexit().
+ * \param func The callback function to unregister.
+ */
+void ast_unregister_atexit(void (*func)(void));
+
+#if !defined(LOW_MEMORY)
+/*!
+ * \brief Register the version of a source code file with the core.
+ * \param file the source file name
+ * \param version the version string (typically a CVS revision keyword string)
+ * \return nothing
+ *
+ * This function should not be called directly, but instead the
+ * ASTERISK_FILE_VERSION macro should be used to register a file with the core.
+ */
+void ast_register_file_version(const char *file, const char *version);
+
+/*!
+ * \brief Unregister a source code file from the core.
+ * \param file the source file name
+ * \return nothing
+ *
+ * This function should not be called directly, but instead the
+ * ASTERISK_FILE_VERSION macro should be used to automatically unregister
+ * the file when the module is unloaded.
+ */
+void ast_unregister_file_version(const char *file);
+
+/*!
+ * \brief Register/unregister a source code file with the core.
+ * \param file the source file name
+ * \param version the version string (typically a CVS revision keyword string)
+ *
+ * This macro will place a file-scope constructor and destructor into the
+ * source of the module using it; this will cause the version of this file
+ * to registered with the Asterisk core (and unregistered) at the appropriate
+ * times.
+ *
+ * Example:
+ *
+ * \code
+ * ASTERISK_FILE_VERSION(__FILE__, "\$Revision\$")
+ * \endcode
+ *
+ * \note The dollar signs above have been protected with backslashes to keep
+ * CVS from modifying them in this file; under normal circumstances they would
+ * not be present and CVS would expand the Revision keyword into the file's
+ * revision number.
+ */
+#ifdef MTX_PROFILE
+#define HAVE_MTX_PROFILE /* used in lock.h */
+#define ASTERISK_FILE_VERSION(file, version) \
+ static int mtx_prof = -1; /* profile mutex */ \
+ static void __attribute__((constructor)) __register_file_version(void) \
+ { \
+ mtx_prof = ast_add_profile("mtx_lock_" file, 0); \
+ ast_register_file_version(file, version); \
+ } \
+ static void __attribute__((destructor)) __unregister_file_version(void) \
+ { \
+ ast_unregister_file_version(file); \
+ }
+#else /* !MTX_PROFILE */
+#define ASTERISK_FILE_VERSION(file, version) \
+ static void __attribute__((constructor)) __register_file_version(void) \
+ { \
+ ast_register_file_version(file, version); \
+ } \
+ static void __attribute__((destructor)) __unregister_file_version(void) \
+ { \
+ ast_unregister_file_version(file); \
+ }
+#endif /* !MTX_PROFILE */
+#else /* LOW_MEMORY */
+#define ASTERISK_FILE_VERSION(file, x)
+#endif /* LOW_MEMORY */
+
+#if !defined(LOW_MEMORY)
+/*!
+ * \brief support for event profiling
+ *
+ * (note, this must be documented a lot more)
+ * ast_add_profile allocates a generic 'counter' with a given name,
+ * which can be shown with the command 'show profile <name>'
+ *
+ * The counter accumulates positive or negative values supplied by
+ * ast_add_profile(), dividing them by the 'scale' value passed in the
+ * create call, and also counts the number of 'events'.
+ * Values can also be taked by the TSC counter on ia32 architectures,
+ * in which case you can mark the start of an event calling ast_mark(id, 1)
+ * and then the end of the event with ast_mark(id, 0).
+ * For non-i386 architectures, these two calls return 0.
+ */
+int ast_add_profile(const char *, uint64_t scale);
+int64_t ast_profile(int, int64_t);
+int64_t ast_mark(int, int start1_stop0);
+#else /* LOW_MEMORY */
+#define ast_add_profile(a, b) 0
+#define ast_profile(a, b) do { } while (0)
+#define ast_mark(a, b) do { } while (0)
+#endif /* LOW_MEMORY */
+
+#endif /* _ASTERISK_H */
diff --git a/include/asterisk/abstract_jb.h b/include/asterisk/abstract_jb.h
new file mode 100644
index 000000000..820e87cea
--- /dev/null
+++ b/include/asterisk/abstract_jb.h
@@ -0,0 +1,226 @@
+/*
+ * 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 <stdio.h>
+#include <sys/time.h>
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+struct ast_channel;
+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.
+ *
+ * \return zero if there are no jitter buffers in use, 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.
+ *
+ * \return zero if the frame was queued, -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, char *varname, 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);
+
+/*!
+ * \brief drops all frames from a jitterbuffer and resets it
+ * \param c0 one channel of a bridge
+ * \param c1 the other channel of the bridge
+ */
+void ast_jb_empty_and_reset(struct ast_channel *c0, struct ast_channel *c1);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _ABSTRACT_JB_H_ */
diff --git a/include/asterisk/acl.h b/include/asterisk/acl.h
new file mode 100644
index 000000000..f9114ce11
--- /dev/null
+++ b/include/asterisk/acl.h
@@ -0,0 +1,57 @@
+/*
+ * 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 <netinet/in.h>
+#include "asterisk/io.h"
+
+#define AST_SENSE_DENY 0
+#define AST_SENSE_ALLOW 1
+
+/* Host based access control */
+
+struct ast_ha;
+
+void ast_free_ha(struct ast_ha *ha);
+struct ast_ha *ast_append_ha(char *sense, char *stuff, struct ast_ha *path);
+int ast_apply_ha(struct ast_ha *ha, struct sockaddr_in *sin);
+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_lookup_iface(char *iface, struct in_addr *address);
+struct ast_ha *ast_duplicate_ha_list(struct ast_ha *original);
+int ast_find_ourip(struct in_addr *ourip, struct sockaddr_in bindaddr);
+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/include/asterisk/adsi.h b/include/asterisk/adsi.h
new file mode 100644
index 000000000..0c894b8f3
--- /dev/null
+++ b/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"
+
+/* 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)
+ *
+ * Returns 0 on success (or adsi unavailable) and -1 on hangup
+ *
+ */
+int ast_adsi_channel_init(struct ast_channel *chan);
+
+int ast_adsi_begin_download(struct ast_channel *chan, char *service, unsigned char *fdn, unsigned char *sec, int version);
+
+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
+ *
+ * Returns 0 on success (or adsi unavailable) and -1 on hangup
+ *
+ */
+int ast_adsi_channel_restore(struct ast_channel *chan);
+
+/*! 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
+ *
+ * Return 0 on success (or adsi unavailable) and -1 on hangup
+ *
+ */
+int ast_adsi_print(struct ast_channel *chan, char **lines, int *align, int voice);
+
+/*! 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
+ *
+ * Returns 0 if scripts is not loaded or not an ADSI CPE. Returns -1
+ * on hangup. Returns 1 if script already loaded.
+ */
+int ast_adsi_load_session(struct ast_channel *chan, unsigned char *app, int ver, int data);
+int ast_adsi_unload_session(struct ast_channel *chan);
+
+/* ADSI Layer 2 transmission functions */
+int ast_adsi_transmit_messages(struct ast_channel *chan, unsigned char **msg, int *msglen, int *msgtype);
+int ast_adsi_transmit_message(struct ast_channel *chan, unsigned char *msg, int msglen, int msgtype);
+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
+ */
+int ast_adsi_read_encoded_dtmf(struct ast_channel *chan, unsigned char *buf, int maxlen);
+
+/* ADSI Layer 3 creation functions */
+
+/*! 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)
+ *
+ * Returns number of bytes added to buffer or -1 on error.
+ *
+ */
+
+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
+ */
+int ast_adsi_query_cpeid(unsigned char *buf);
+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.
+ */
+int ast_adsi_get_cpeid(struct ast_channel *chan, unsigned char *cpeid, int voice);
+
+int ast_adsi_get_cpeinfo(struct ast_channel *chan, int *width, int *height, int *buttons, int voice);
+
+/*! 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)
+ *
+ * Returns number of bytes added to buffer or -1 on error.
+ *
+ */
+
+int ast_adsi_download_connect(unsigned char *buf, char *service, unsigned char *fdn, unsigned char *sec, int ver);
+
+/*! Disconnects a running session */
+/*!
+ * \param buf Character buffer to create parameter in (must have at least 256 free)
+ *
+ * Returns number of bytes added to buffer or -1 on error.
+ *
+ */
+int ast_adsi_disconnect_session(unsigned char *buf);
+
+/*! Disconnects (and hopefully saves) a downloaded script */
+/*!
+ * \param buf Character buffer to create parameter in (must have at least 256 free)
+ *
+ * Returns number of bytes added to buffer or -1 on error.
+ *
+ */
+int ast_adsi_download_disconnect(unsigned char *buf);
+
+/*! Puts CPE in data mode... */
+/*!
+ * \param buf Character buffer to create parameter in (must have at least 256 free)
+ *
+ * Returns number of bytes added to buffer or -1 on error.
+ *
+ */
+int ast_adsi_data_mode(unsigned char *buf);
+int ast_adsi_clear_soft_keys(unsigned char *buf);
+int ast_adsi_clear_screen(unsigned char *buf);
+
+/*! 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
+ *
+ * Returns number of bytes added to buffer or -1 on error.
+ *
+ */
+int ast_adsi_voice_mode(unsigned char *buf, int when);
+
+/*! Returns non-zero if Channel does or might support ADSI */
+/*!
+ * \param chan Channel to check
+ *
+ */
+int ast_adsi_available(struct ast_channel *chan);
+
+/*! 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
+ *
+ * Returns number of bytes added to buffer or -1 on error.
+ *
+ */
+
+int ast_adsi_display(unsigned char *buf, int page, int line, int just, int wrap, char *col1, char *col2);
+
+/*! 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)
+ *
+ * Returns number of bytes added to buffer or -1 on error.
+ *
+ */
+
+int ast_adsi_set_line(unsigned char *buf, int page, int line);
+
+/*! 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
+ *
+ * Returns number of bytes added to buffer or -1 on error.
+ *
+ */
+int ast_adsi_load_soft_key(unsigned char *buf, int key, const char *llabel, const char *slabel, const char *ret, int data);
+
+/*! 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
+ *
+ * Returns number of bytes added to buffer or -1 on error.
+ *
+ */
+int ast_adsi_set_keys(unsigned char *buf, unsigned char *keys);
+
+/*! 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)
+ *
+ * Returns number of bytes added to buffer or -1 on error.
+ *
+ */
+int ast_adsi_input_control(unsigned char *buf, int page, int line, int display, int format, int just);
+
+/*! 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
+ *
+ * Returns number of bytes added to buffer or -1 on error.
+ *
+ */
+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/include/asterisk/ael_structs.h b/include/asterisk/ael_structs.h
new file mode 100644
index 000000000..a5a1fd0cc
--- /dev/null
+++ b/include/asterisk/ael_structs.h
@@ -0,0 +1,195 @@
+#ifndef _ASTERISK_AEL_STRUCTS_H
+#define _ASTERISK_AEL_STRUCTS_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
+
+
+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 */
+
+} 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 */
+ 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;
+
+#if 0
+pval *npval(pvaltype type, int first_line, int last_line, int first_column, int last_column);
+void linku1(pval *head, pval *tail);
+void print_pval_list(FILE *f, pval *item, int depth);
+void print_pval(FILE *f, pval *item, int depth);
+void ael2_semantic_check(pval *item, int *errs, int *warns, int *notes);
+struct pval *find_label_in_current_context(char *exten, char *label);
+struct pval *find_label_in_current_extension(char *label);
+int count_labels_in_current_context(char *label);
+struct pval *find_label_in_current_db(char *context, char *exten, char *label);
+void ael2_print(char *fname, pval *tree);
+#endif
+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;
+ int has_switch; /* set if a switch exists in the extension */
+ int checked_switch; /* set if we checked for a switch in the extension -- so we don't have to do it again */
+
+ 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/include/asterisk/aes.h b/include/asterisk/aes.h
new file mode 100644
index 000000000..af648e8ee
--- /dev/null
+++ b/include/asterisk/aes.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_H
+#define _AES_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/include/asterisk/agi.h b/include/asterisk/agi.h
new file mode 100644
index 000000000..5797176fe
--- /dev/null
+++ b/include/asterisk/agi.h
@@ -0,0 +1,57 @@
+/*
+ * 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 */
+} 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;
+ struct agi_command *next;
+} agi_command;
+
+int ast_agi_register(agi_command *cmd);
+void ast_agi_unregister(agi_command *cmd);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _ASTERISK_AGI_H */
diff --git a/include/asterisk/alaw.h b/include/asterisk/alaw.h
new file mode 100644
index 000000000..44b3bad86
--- /dev/null
+++ b/include/asterisk/alaw.h
@@ -0,0 +1,43 @@
+/*
+ * 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
+
+/*! Init the ulaw conversion stuff */
+/*!
+ * To init the ulaw to slinear conversion stuff, this needs to be run.
+ */
+void ast_alaw_init(void);
+
+/*! converts signed linear to mulaw */
+/*!
+ */
+extern unsigned char __ast_lin2a[8192];
+
+/*! help */
+extern short __ast_alaw[256];
+
+#define AST_LIN2A(a) (__ast_lin2a[((unsigned short)(a)) >> 3])
+#define AST_ALAW(a) (__ast_alaw[(int)(a)])
+
+#endif /* _ASTERISK_ALAW_H */
diff --git a/include/asterisk/app.h b/include/asterisk/app.h
new file mode 100644
index 000000000..e23b3b477
--- /dev/null
+++ b/include/asterisk/app.h
@@ -0,0 +1,434 @@
+/*
+ * 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
+
+#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[@context] */
+ 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)
+ * \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, 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);
+
+/*! Determine if a given mailbox has any voicemail */
+int ast_app_has_voicemail(const char *mailbox, const char *folder);
+
+/*! Determine number of new/old messages in a mailbox */
+int ast_app_inboxcount(const char *mailbox, int *newmsgs, int *oldmsgs);
+
+/*! Determine number of messages in a given mailbox and folder */
+int ast_app_messagecount(const char *context, const char *mailbox, const char *folder);
+
+/*! 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 temporaraly 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.
+*/
+int ast_dtmf_stream(struct ast_channel *chan, struct ast_channel *peer, const char *digits, int between);
+
+/*! Stream a filename (or file descriptor) as a generator. */
+int ast_linear_stream(struct ast_channel *chan, const char *filename, int fd, int allowoverride);
+
+/*! Stream a file with fast forward, pause, reverse, restart. */
+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);
+
+/*! 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);
+
+/*! 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);
+
+/*! 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
+\n
+ 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 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);
+
+/*! Unlock a path */
+int ast_unlock_path(const char *path);
+
+/*! Read a file into asterisk*/
+char *ast_read_textfile(const char *file);
+
+struct ast_group_info {
+ struct ast_channel *chan;
+ char *category;
+ char *group;
+ AST_LIST_ENTRY(ast_group_info) list;
+};
+
+/*! 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);
+
+/*! 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);
+
+/*! Get the current channel count of the specified group and category. */
+int ast_app_group_get_count(const char *group, const char *category);
+
+/*! 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);
+
+/*! Discard all group counting for a channel */
+int ast_app_group_discard(struct ast_channel *chan);
+
+/*! Update all group counting for a channel to a new one */
+int ast_app_group_update(struct ast_channel *oldchan, struct ast_channel *newchan);
+
+/*! Lock the group count list */
+int ast_app_group_list_lock(void);
+
+/*! Get the head of the group count list */
+struct ast_group_info *ast_app_group_list_head(void);
+
+/*! 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) - offsetof(typeof(args), argv)) / 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) - offsetof(typeof(args), argv)) / 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. */
+ unsigned int 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)) {
+ LOCAL_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 Given a list of options array, return an option string based on passed flags
+ \param options The array of possible options declared with AST_APP_OPTIONS
+ \param flags The flags of the options that you wish to populate the buffer with
+ \param buf The buffer to fill with the string of options
+ \param len The maximum length of buf
+*/
+void ast_app_options2str(const struct ast_app_option *options, struct ast_flags *flags, char *buf, size_t len);
+
+/*! \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);
+
+/*! 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);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _ASTERISK_APP_H */
diff --git a/include/asterisk/ast_expr.h b/include/asterisk/ast_expr.h
new file mode 100644
index 000000000..bc0331309
--- /dev/null
+++ b/include/asterisk/ast_expr.h
@@ -0,0 +1,32 @@
+/*
+ * 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_EXPR_H
+#define _ASTERISK_EXPR_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+int ast_expr(char *expr, char *buf, int length);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _ASTERISK_EXPR_H */
diff --git a/include/asterisk/astdb.h b/include/asterisk/astdb.h
new file mode 100644
index 000000000..828fe9725
--- /dev/null
+++ b/include/asterisk/astdb.h
@@ -0,0 +1,52 @@
+/*
+ * 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];
+};
+
+int ast_db_get(const char *family, const char *key, char *out, int outlen);
+
+int ast_db_put(const char *family, const char *key, char *value);
+
+int ast_db_del(const char *family, const char *key);
+
+int ast_db_deltree(const char *family, const char *keytree);
+
+struct ast_db_entry *ast_db_gettree(const char *family, const char *keytree);
+
+void ast_db_freetree(struct ast_db_entry *entry);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _ASTERISK_ASTDB_H */
diff --git a/include/asterisk/astmm.h b/include/asterisk/astmm.h
new file mode 100644
index 000000000..8e63c85c5
--- /dev/null
+++ b/include/asterisk/astmm.h
@@ -0,0 +1,89 @@
+/*
+ * 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"
+
+/* Include these now to prevent them from being needed later */
+#include <sys/types.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdarg.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, ...) __attribute__((format(printf, 5, 6)));
+int __ast_vasprintf(char **strp, const char *format, va_list ap, const char *file, int lineno, const char *func) __attribute__((format(printf, 2, 0)));
+
+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/include/asterisk/astobj.h b/include/asterisk/astobj.h
new file mode 100644
index 000000000..4f29514b1
--- /dev/null
+++ b/include/asterisk/astobj.h
@@ -0,0 +1,824 @@
+/*
+ * 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 <string.h>
+
+#include "asterisk/lock.h"
+#include "asterisk/compiler.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)
+
+#define ASTOBJ_TRYWRLOCK(object) ast_mutex_trylock(&(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", s); } while(0))
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _ASTERISK_ASTOBJ_H */
diff --git a/include/asterisk/astobj2.h b/include/asterisk/astobj2.h
new file mode 100644
index 000000000..dd154ec85
--- /dev/null
+++ b/include/asterisk/astobj2.h
@@ -0,0 +1,560 @@
+/*
+ * 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
+
+#include "asterisk/compat.h"
+
+/*! \file
+ *
+ * \brief Object Model implementing objects and containers.
+
+These functions implement an abstraction for objects (with
+locks and reference counts) and containers for these user-defined objects,
+supporting locking, reference counting and callbacks.
+
+The internal implementation of the container is opaque to the user,
+so we can use different data structures as needs arise.
+
+At the moment, however, the only internal data structure is a hash
+table. When other structures will be implemented, the initialization
+function may change.
+
+USAGE - OBJECTS
+
+An object is a block of memory that must be allocated with the
+function ao2_alloc(), and for which the system keeps track (with
+abit of help from the programmer) of the number of references around.
+When an object has no more references, it is destroyed, by first
+invoking whatever 'destructor' function the programmer specifies
+(it can be NULL), and then freeing the memory.
+This way objects can be shared without worrying who is in charge
+of freeing them.
+
+Basically, 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 object returned has a refcount = 1.
+Note that the memory for the object is allocated 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.
+
+
+- other calls on the object are ao2_lock(obj), ao2_unlock(),
+ ao2_trylock(), to manipulate the lock.
+
+
+USAGE - CONTAINERS
+
+A containers is an abstract data structure where we can store
+objects, search them (hopefully in an efficient way), and iterate
+or apply a callback function to them. A container is just an 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);
+
+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 moduly 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 object itself,
+other than the fact that it has been created by ao2_alloc()
+All knowledge of the (user-defined) internals of the object
+is left to the (user-supplied) functions passed as arguments
+to ao2_container_alloc().
+
+If we want to insert the object in the 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 extractiong 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.
+
+Objects implement a reference counter keeping the count
+of the number of references that reference an object.
+
+When this number becomes zero the destructor will be
+called and the object will be free'd.
+ */
+
+/*!
+ * Invoked just before freeing the memory for the object.
+ * It is passed a pointer to user data.
+ */
+typedef void (*ao2_destructor_fn)(void *);
+
+void ao2_bt(void); /* backtrace */
+/*!
+ * Allocate and initialize an object.
+ *
+ * \param data_size The sizeof() of user-defined structure.
+ * \param destructor_fn The function destructor (can be NULL)
+ * \return A pointer to user data.
+ *
+ * Allocates a struct astobj2 with sufficient space for the
+ * user-defined structure.
+ * \notes:
+ * - 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);
+
+/*!
+ * 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);
+
+/*!
+ * Lock an object.
+ *
+ * \param a A pointer to the object we want lock.
+ * \return 0 on success, other values on error.
+ */
+#ifndef DEBUG_THREADS
+int ao2_lock(void *a);
+#else
+#define ao2_lock(a) _ao2_lock(a, __FILE__, __PRETTY_FUNCTION__, __LINE__, #a)
+int _ao2_lock(void *a, const char *file, const char *func, int line, const char *var);
+#endif
+
+#ifndef DEBUG_THREADS
+int ao2_trylock(void *a);
+#else
+#define ao2_trylock(a) _ao2_trylock(a, __FILE__, __PRETTY_FUNCTION__, __LINE__, #a)
+int _ao2_trylock(void *a, const char *file, const char *func, int line, const char *var);
+#endif
+
+/*!
+ * Unlock an object.
+ *
+ * \param a A pointer to the object we want unlock.
+ * \return 0 on success, other values on error.
+ */
+#ifndef DEBUG_THREADS
+int ao2_unlock(void *a);
+#else
+#define ao2_unlock(a) _ao2_unlock(a, __FILE__, __PRETTY_FUNCTION__, __LINE__, #a)
+int _ao2_unlock(void *a, const char *file, const char *func, int line, const char *var);
+#endif
+
+/*!
+ *
+ * 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.
+
+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 = ao2_container_alloc(size, cmp_fn, hash_fn)
+ allocate a container with desired size and default compare
+ and hash function
+
+ 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.
+
+ 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.
+
+ iterate on a container
+ this is done with the following sequence
+
+ 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);
+ }
+
+ The difference with the callback is that the control
+ on how to iterate is left to us.
+
+ ao2_ref(c, -1)
+ dropping a reference to a container destroys it, very simple!
+
+Containers are astobj2 object themselves, and this is why their
+implementation is simple too.
+
+ */
+
+/*!
+ * We can perform different operation on an object. We do this
+ * according the following flags.
+ */
+enum search_flags {
+ /*! unlink the object found */
+ OBJ_UNLINK = (1 << 0),
+ /*! on match, don't return the object or increase its reference count. */
+ OBJ_NODATA = (1 << 1),
+ /*! don't stop at the first match
+ * \note This is not fully implemented. */
+ OBJ_MULTIPLE = (1 << 2),
+ /*! obj is an object of the same type as the one being searched for.
+ * This implies that it can be passed to the object's hash function
+ * for optimized searching. */
+ OBJ_POINTER = (1 << 3),
+};
+
+/*!
+ * Type of a generic function to generate a hash value from an object.
+ *
+ */
+typedef int (*ao2_hash_fn)(const void *obj, const int flags);
+
+/*!
+ * valid callback results:
+ * We return a combination of
+ * CMP_MATCH when the object matches the request,
+ * and CMP_STOP when we should not continue the search further.
+ */
+enum _cb_results {
+ CMP_MATCH = 0x1,
+ CMP_STOP = 0x2,
+};
+
+/*!
+ * generic function to compare objects.
+ * This, as other callbacks, should return a combination of
+ * _cb_results as described above.
+ *
+ * \param o object from container
+ * \param arg search parameters (directly from ao2_find)
+ * \param flags passed directly from ao2_find
+ * XXX explain.
+ */
+
+/*!
+ * 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 the same as a compare function.
+ * In fact, they are the same thing.
+ */
+typedef int (*ao2_callback_fn)(void *obj, void *arg, int flags);
+
+/*!
+ * Here start declarations of containers.
+ */
+struct ao2_container;
+
+/*!
+ * 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 my_hash_fn Pointer to a function computing a hash value.
+ * \param my_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 unsigned int n_buckets,
+ ao2_hash_fn hash_fn, ao2_callback_fn cmp_fn);
+
+/*!
+ * Returns the number of elements in a container.
+ */
+int ao2_container_count(struct ao2_container *c);
+
+/*
+ * 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.
+ *
+ * \return NULL on errors, other values 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 to the object that the container now holds.
+ *
+ * For Asterisk 1.4 only, there is a dirty hack here to ensure that chan_iax2
+ * can have objects linked in to the container at the head instead of tail
+ * when it is just a linked list. This is to maintain some existing behavior
+ * where the order must be maintained as it was before this conversion so that
+ * matching behavior doesn't change.
+ */
+#define ao2_link(c, o) __ao2_link(c, o, 0)
+void *__ao2_link(struct ao2_container *c, void *newobj, int iax2_hack);
+
+/*!
+ * \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);
+
+/*! \struct 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 */
+};
+
+/*!
+ * ao2_callback() and astob2_find() are the same thing with only one difference:
+ * the latter uses as a callback the function passed as my_cmp_f() at
+ * the time of the creation of the container.
+ *
+ * \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.
+ *
+ * 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.
+ */
+/* XXX order of arguments to find */
+void *ao2_find(struct ao2_container *c, void *arg, enum search_flags flags);
+void *ao2_callback(struct ao2_container *c,
+ enum search_flags flags,
+ ao2_callback_fn cb_fn, void *arg);
+
+int ao2_match_by_addr(void *user_data, void *arg, int flags);
+/*!
+ *
+ *
+ * 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
+ *
+ */
+
+/*!
+ * 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 */
+ unsigned int c_version;
+ /*! pointer to the current object */
+ void *obj;
+ /*! container version when the object was created */
+ unsigned int version;
+};
+
+struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags);
+
+void *ao2_iterator_next(struct ao2_iterator *a);
+
+#endif /* _ASTERISK_ASTOBJ2_H */
diff --git a/include/asterisk/astosp.h b/include/asterisk/astosp.h
new file mode 100644
index 000000000..75ee76fc5
--- /dev/null
+++ b/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/include/asterisk/audiohook.h b/include/asterisk/audiohook.h
new file mode 100644
index 000000000..8839cbde4
--- /dev/null
+++ b/include/asterisk/audiohook.h
@@ -0,0 +1,211 @@
+/*
+ * 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
+
+#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 */
+ AST_AUDIOHOOK_TRIGGER_SYNC = (1 << 2), /*!< Audiohook wants to be triggered when both sides have combined audio available */
+};
+
+#define AST_AUDIOHOOK_SYNC_TOLERANCE 100 /*< Tolerance in milliseconds for audiohooks synchronization */
+
+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 */
+ struct timeval read_time; /*!< Last time read factory was fed */
+ struct timeval write_time; /*!< Last time write factory was fed */
+ 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 Move an audiohook from one channel to a new one
+ *
+ * \todo Currently only the first audiohook of a specific source found will be moved.
+ * We should add the capability to move multiple audiohooks from a single source as well.
+ *
+ * \note It is required that both old_chan and new_chan are locked prior to calling
+ * this function. Besides needing to protect the data within the channels, not locking
+ * these channels can lead to a potential deadlock
+ *
+ * \param old_chan The source of the audiohook to move
+ * \param new_chan The destination to which we want the audiohook to move
+ * \param source The source of the audiohook we want to move
+ */
+void ast_audiohook_move_by_source(struct ast_channel *old_chan, struct ast_channel *new_chan, const char *source);
+
+/*! \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
+ */
+int ast_audiohook_detach_source(struct ast_channel *chan, const char *source);
+
+/*!
+ * \brief Remove an audiohook from a specified channel
+ *
+ * \param chan Channel to remove from
+ * \param audiohook Audiohook to remove
+ *
+ * \return Returns 0 on success, -1 on failure
+ *
+ * \note The channel does not need to be locked before calling this function
+ */
+int ast_audiohook_remove(struct ast_channel *chan, struct ast_audiohook *audiohook);
+
+/*! \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 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/include/asterisk/autoconfig.h.in b/include/asterisk/autoconfig.h.in
new file mode 100644
index 000000000..b05c0ff32
--- /dev/null
+++ b/include/asterisk/autoconfig.h.in
@@ -0,0 +1,713 @@
+/* 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 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 to indicate the ${ALSA_DESCRIP} library */
+#undef HAVE_ALSA
+
+/* Define to 1 if you have the <arpa/inet.h> header file. */
+#undef HAVE_ARPA_INET_H
+
+/* Define to 1 if you have the <arpa/nameser.h> header file. */
+#undef HAVE_ARPA_NAMESER_H
+
+/* Define to 1 if you have the `asprintf' function. */
+#undef HAVE_ASPRINTF
+
+/* 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 to 1 if you have the `bzero' function. */
+#undef HAVE_BZERO
+
+/* Define to indicate the ${CAP_DESCRIP} library */
+#undef HAVE_CAP
+
+/* Define to 1 if your system has a working `chown' function. */
+#undef HAVE_CHOWN
+
+/* Define if your system has the curl libraries. */
+#undef HAVE_CURL
+
+/* Define to indicate the ${CURSES_DESCRIP} library */
+#undef HAVE_CURSES
+
+/* Define if your system has the DAHDI headers. */
+#undef HAVE_DAHDI
+
+/* Define DAHDI headers version */
+#undef HAVE_DAHDI_VERSION
+
+/* 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 you have the <fcntl.h> header file. */
+#undef HAVE_FCNTL_H
+
+/* Define to 1 if you have the `floor' function. */
+#undef HAVE_FLOOR
+
+/* Define to 1 if you have the `fork' function. */
+#undef HAVE_FORK
+
+/* Define to indicate the ${FREETDS_DESCRIP} library */
+#undef HAVE_FREETDS
+
+/* 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 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 if your system has the GETIFADDRS headers. */
+#undef HAVE_GETIFADDRS
+
+/* Define GETIFADDRS headers version */
+#undef HAVE_GETIFADDRS_VERSION
+
+/* 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 indicate the ${GNUTLS_DESCRIP} library */
+#undef HAVE_GNUTLS
+
+/* 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 to indicate the ${IKSEMEL_DESCRIP} library */
+#undef HAVE_IKSEMEL
+
+/* 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_ntoa' function. */
+#undef HAVE_INET_NTOA
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the `ioperm' function. */
+#undef HAVE_IOPERM
+
+/* Define to 1 if your system has PMTU discovery on UDP sockets. */
+#undef HAVE_IP_MTU_DISCOVER
+
+/* Define to 1 if you have the `isascii' function. */
+#undef HAVE_ISASCII
+
+/* Define to indicate the ${ISDNNET_DESCRIP} library */
+#undef HAVE_ISDNNET
+
+/* Define to 1 if you have the <libintl.h> header file. */
+#undef HAVE_LIBINTL_H
+
+/* Define if your system has the KDE libraries. */
+#undef HAVE_LIBKDE
+
+/* 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 to indicate the ${LTDL_DESCRIP} library */
+#undef HAVE_LTDL
+
+/* 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 to indicate the ${MISDN_DESCRIP} library */
+#undef HAVE_MISDN
+
+/* 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 to indicate the ${NBS_DESCRIP} library */
+#undef HAVE_NBS
+
+/* Define to indicate the ${NCURSES_DESCRIP} library */
+#undef HAVE_NCURSES
+
+/* 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 to indicate the Net-SNMP library */
+#undef HAVE_NETSNMP
+
+/* Define to indicate the ${NEWT_DESCRIP} library */
+#undef HAVE_NEWT
+
+/* Define to indicate the ${OGG_DESCRIP} library */
+#undef HAVE_OGG
+
+/* Define if your system has the OpenH323 libraries. */
+#undef HAVE_OPENH323
+
+/* Define to indicate the ${OPENSSL_DESCRIP} library */
+#undef HAVE_OPENSSL
+
+/* Define to indicate the ${OSPTK_DESCRIP} library */
+#undef HAVE_OSPTK
+
+/* Define to indicate the ${OSS_DESCRIP} library */
+#undef HAVE_OSS
+
+/* Define to 1 if OSX atomic operations are supported. */
+#undef HAVE_OSX_ATOMICS
+
+/* Define to indicate the PostgreSQL library */
+#undef HAVE_PGSQL
+
+/* Define to indicate the ${POPT_DESCRIP} library */
+#undef HAVE_POPT
+
+/* Define to 1 if you have the `pow' function. */
+#undef HAVE_POW
+
+/* Define to indicate the ${PRI_DESCRIP} library */
+#undef HAVE_PRI
+
+/* Define to indicate the ${PRI_INBANDDISCONNECT_DESCRIP} library */
+#undef HAVE_PRI_INBANDDISCONNECT
+
+/* Define to indicate the ${PRI_VERSION_DESCRIP} library */
+#undef HAVE_PRI_VERSION
+
+/* Define if you have POSIX threads libraries and header files. */
+#undef HAVE_PTHREAD
+
+/* Define to 1 if your system has PTHREAD_RWLOCK_INITIALIZER. */
+#undef HAVE_PTHREAD_RWLOCK_INITIALIZER
+
+/* Define to 1 if your system has PTHREAD_RWLOCK_PREFER_WRITER_NP. */
+#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 to indicate the ${RADIUS_DESCRIP} library */
+#undef HAVE_RADIUS
+
+/* Define to 1 if you have the `regcomp' function. */
+#undef HAVE_REGCOMP
+
+/* 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 to 1 if you have the `rint' function. */
+#undef HAVE_RINT
+
+/* Define to 1 if your system has a dynamic linker that supports RTLD_NOLOAD.
+ */
+#undef HAVE_RTLD_NOLOAD
+
+/* Define to 1 if your system has /sbin/launchd. */
+#undef HAVE_SBIN_LAUNCHD
+
+/* 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 to 1 if you have the `socket' function. */
+#undef HAVE_SOCKET
+
+/* Define to 1 if your system has soxmix application. */
+#undef HAVE_SOXMIX
+
+/* Define to indicate the ${SPEEX_DESCRIP} library */
+#undef HAVE_SPEEX
+
+/* Define to indicate the ${SPEEXDSP_DESCRIP} library */
+#undef HAVE_SPEEXDSP
+
+/* Define to indicate the ${SPEEX_PREPROCESS_DESCRIP} library */
+#undef HAVE_SPEEX_PREPROCESS
+
+/* Define to indicate the ${SQLITE_DESCRIP} library */
+#undef HAVE_SQLITE
+
+/* Define to 1 if you have the `sqrt' function. */
+#undef HAVE_SQRT
+
+/* 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 to 1 if you have the `strtol' function. */
+#undef HAVE_STRTOL
+
+/* 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 to indicate the ${SUPPSERV_DESCRIP} library */
+#undef HAVE_SUPPSERV
+
+/* 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 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/io.h> header file. */
+#undef HAVE_SYS_IO_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 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 to indicate the ${TERMCAP_DESCRIP} library */
+#undef HAVE_TERMCAP
+
+/* Define to 1 if you have the <termios.h> header file. */
+#undef HAVE_TERMIOS_H
+
+/* Define to 1 if your system has timersub in time.h */
+#undef HAVE_TIMERSUB
+
+/* Define to indicate the ${TINFO_DESCRIP} library */
+#undef HAVE_TINFO
+
+/* Define to indicate the ${TONEZONE_DESCRIP} library */
+#undef HAVE_TONEZONE
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to indicate the ${UNIXODBC_DESCRIP} library */
+#undef HAVE_UNIXODBC
+
+/* Define to 1 if you have the `unsetenv' function. */
+#undef HAVE_UNSETENV
+
+/* Define to indicate the ${USB_DESCRIP} library */
+#undef HAVE_USB
+
+/* 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 indicate the ${VORBIS_DESCRIP} library */
+#undef HAVE_VORBIS
+
+/* 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 `fork' works. */
+#undef HAVE_WORKING_FORK
+
+/* Define to 1 if `vfork' works. */
+#undef HAVE_WORKING_VFORK
+
+/* Define if your system has the Zaptel headers. */
+#undef HAVE_ZAPTEL
+
+/* Define if your Zaptel drivers have chan_alarms. */
+#undef HAVE_ZAPTEL_CHANALARMS
+
+/* Define to indicate the ${ZLIB_DESCRIP} library */
+#undef HAVE_ZLIB
+
+/* 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/include/asterisk/callerid.h b/include/asterisk/callerid.h
new file mode 100644
index 000000000..7347dd9d0
--- /dev/null
+++ b/include/asterisk/callerid.h
@@ -0,0 +1,339 @@
+/*
+ * 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.
+ *
+ */
+
+/*!
+ * \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_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 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);
+
+/*! \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/include/asterisk/causes.h b/include/asterisk/causes.h
new file mode 100644
index 000000000..d76277d54
--- /dev/null
+++ b/include/asterisk/causes.h
@@ -0,0 +1,83 @@
+/*
+ * 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
+
+/* Causes for disconnection (from Q.931) */
+#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_SUBSCRIBER_ABSENT 20
+#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_SUBSCRIBER_ABSENT
+#define AST_CAUSE_NOTDEFINED 0
+#define AST_CAUSE_NOSUCHDRIVER AST_CAUSE_CHAN_NOT_IMPLEMENTED
+
+#endif /* _ASTERISK_CAUSES_H */
diff --git a/include/asterisk/cdr.h b/include/asterisk/cdr.h
new file mode 100644
index 000000000..74f6a0ab1
--- /dev/null
+++ b/include/asterisk/cdr.h
@@ -0,0 +1,342 @@
+/*
+ * 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>
+
+/*! Flags */
+#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)
+#define AST_CDR_FLAG_BRIDGED (1 << 5)
+#define AST_CDR_FLAG_MAIN (1 << 6)
+#define AST_CDR_FLAG_ENABLE (1 << 7)
+#define AST_CDR_FLAG_ANSLOCKED (1 << 8)
+#define AST_CDR_FLAG_DONT_TOUCH (1 << 9)
+#define AST_CDR_FLAG_DIALED (1 << 10)
+
+/*! Disposition */
+#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)
+
+/*! 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"
+
+/*! 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;
+};
+
+int ast_cdr_isset_unanswered(void);
+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, char *buf, size_t size, 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);
+
+typedef int (*ast_cdrbe)(struct ast_cdr *cdr);
+
+/*! \brief Allocate a CDR record
+ * Returns a malloc'd ast_cdr structure, returns NULL on error (malloc failure)
+ */
+struct ast_cdr *ast_cdr_alloc(void);
+
+/*! \brief Duplicate a record
+ * Returns a malloc'd ast_cdr structure, returns 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 is negligible. (returns 0 by default)
+ */
+int ast_cdr_init(struct ast_cdr *cdr, struct ast_channel *chan);
+
+/*! 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 is negligible. (returns 0 by default)
+ */
+int ast_cdr_setcid(struct ast_cdr *cdr, struct ast_channel *chan);
+
+/*! 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.
+ * Returns -1 on error, 0 on success.
+ */
+int ast_cdr_register(const char *name, const char *desc, ast_cdrbe be);
+
+/*! 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);
+
+/*! 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);
+
+/*! 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
+ * NULL argument is just fine.
+ */
+void ast_cdr_answer(struct ast_cdr *cdr);
+
+/*! A call wasn't answered */
+/*!
+ * \param cdr the cdr you wish to associate with the call
+ * Marks the channel disposition as "NO ANSWER"
+ * Will skip CDR's in chain with ANS_LOCK bit set. (see
+ * forkCDR() application.
+ */
+extern void ast_cdr_noanswer(struct ast_cdr *cdr);
+
+/*! Busy a call */
+/*!
+ * \param cdr the cdr you wish to associate with the call
+ * Marks the channel disposition as "BUSY"
+ * Will skip CDR's in chain with ANS_LOCK bit set. (see
+ * forkCDR() application.
+ * Returns nothing
+ */
+void ast_cdr_busy(struct ast_cdr *cdr);
+
+/*! Fail a call */
+/*!
+ * \param cdr the cdr you wish to associate with the call
+ * Marks the channel disposition as "FAILED"
+ * Will skip CDR's in chain with ANS_LOCK bit set. (see
+ * forkCDR() application.
+ * Returns nothing
+ */
+void ast_cdr_failed(struct ast_cdr *cdr);
+
+/*! 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);
+
+/*! 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);
+
+/*! 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);
+
+/*! 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);
+
+/*! 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);
+
+/*! 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);
+
+/*! 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.
+ * Returns the binary form of the flag
+ */
+int ast_cdr_amaflags2int(const char *flag);
+
+/*! Disposition to a string */
+/*!
+ * \param disposition input binary form
+ * Converts the binary form of a disposition to string form.
+ * Returns a pointer to the string form
+ */
+char *ast_cdr_disp2str(int disposition);
+
+/*! 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);
+
+/*! Reset the detail record times, flags */
+/*!
+ * \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_specialized_reset(struct ast_cdr *cdr, struct ast_flags *flags);
+
+/*! 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);
+
+/*! 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);
+
+int ast_cdr_setaccount(struct ast_channel *chan, const char *account);
+int ast_cdr_setamaflags(struct ast_channel *chan, const char *amaflags);
+
+
+int ast_cdr_setuserfield(struct ast_channel *chan, const char *userfield);
+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);
+
+/*! Reload the configuration file cdr.conf and start/stop CDR scheduling thread */
+int ast_cdr_engine_reload(void);
+
+/*! 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/include/asterisk/channel.h b/include/asterisk/channel.h
new file mode 100644
index 000000000..7ae0dbeb5
--- /dev/null
+++ b/include/asterisk/channel.h
@@ -0,0 +1,1442 @@
+/*
+ * 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
+
+*/
+
+#ifndef _ASTERISK_CHANNEL_H
+#define _ASTERISK_CHANNEL_H
+
+#include "asterisk/abstract_jb.h"
+
+#include <unistd.h>
+#ifdef POLLCOMPAT
+#include "asterisk/poll-compat.h"
+#else
+#include <sys/poll.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/compat.h"
+#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"
+#include "asterisk/compiler.h"
+
+#define DATASTORE_INHERIT_FOREVER INT_MAX
+
+#define AST_MAX_FDS 8
+/*
+ * 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;
+
+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 unlocked, but is called in
+ * the context of the channel thread so we know the channel is not going
+ * to disappear. This callback is responsible for locking the channel as
+ * necessary. */
+ int (*generate)(struct ast_channel *chan, void *data, int len, int samples);
+};
+
+/*! \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 Fix up channel references
+ *
+ * \arg data The datastore data
+ * \arg old_chan The old channel owning the datastore
+ * \arg new_chan The new channel owning the datastore
+ *
+ * This is exactly like the fixup callback of the channel technology interface.
+ * It allows a datastore to fix any pointers it saved to the owning channel
+ * in case that the owning channel has changed. Generally, this would happen
+ * when the datastore is set to be inherited, and a masquerade occurs.
+ *
+ * \return nothing.
+ */
+ void (*chan_fixup)(void *data, struct ast_channel *old_chan, struct ast_channel *new_chan);
+};
+
+/*! \brief Structure for a channel data store */
+struct ast_datastore {
+ 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.
+ */
+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 */
+ 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 */
+ int (* const send_digit_begin)(struct ast_channel *chan, char digit);
+
+ /*! \brief Stop sending a literal DTMF digit */
+ 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 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 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, 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, 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);
+};
+
+#define DEBUGCHAN_FLAG 0x80000000
+#define FRAMECOUNT_INC(x) ( ((x) & DEBUGCHAN_FLAG) | (((x)+1) & ~DEBUGCHAN_FLAG) )
+
+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 {
+ /*! Channel is down and available */
+ AST_STATE_DOWN,
+ /*! Channel is down, but reserved */
+ AST_STATE_RESERVED,
+ /*! Channel is off hook */
+ AST_STATE_OFFHOOK,
+ /*! Digits (or equivalent) have been dialed */
+ AST_STATE_DIALING,
+ /*! Line is ringing */
+ AST_STATE_RING,
+ /*! Remote end is ringing */
+ AST_STATE_RINGING,
+ /*! Line is up */
+ AST_STATE_UP,
+ /*! Line is busy */
+ AST_STATE_BUSY,
+ /*! Digits (or equivalent) have been dialed while offhook */
+ AST_STATE_DIALING_OFFHOOK,
+ /*! Channel has detected an incoming call and is waiting for ring */
+ AST_STATE_PRERING,
+
+ /*! Do not transmit voice data */
+ AST_STATE_MUTE = (1 << 16),
+};
+
+/*! \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 {
+ /*! \brief Technology (point to channel driver) */
+ const struct ast_channel_tech *tech;
+
+ /*! \brief Private data used by the technology driver */
+ void *tech_pvt;
+
+ 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 */
+ );
+
+ /*! \brief File descriptor for channel -- Drivers will poll on these file descriptors, so at least one must be non -1. */
+ int fds[AST_MAX_FDS];
+
+ void *music_state; /*!< Music State*/
+ void *generatordata; /*!< Current generator data if there is any */
+ struct ast_generator *generator; /*!< Current active data generator */
+
+ /*! \brief 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 *_bridge;
+ 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 */
+
+ /*! \brief Whether or not we have been hung up... Do not set this value
+ directly, use ast_softhangup */
+ int _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; /*!< Lock, can be used to lock a channel for some operations */
+ 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 unused_old_dtmfq[AST_MAX_EXTENSION]; /*!< The DTMFQ is deprecated. All frames should go to the readq. */
+ 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 tone_zone *zone; /*!< Tone zone as set in indications.conf or
+ in the CHANNEL dialplan function */
+
+ struct ast_channel_monitor *monitor; /*!< Channel monitoring */
+
+ /*! Track the read/written samples for monitor use */
+ unsigned long insmpl;
+ unsigned long outsmpl;
+
+ /* Frames in/out counters. The high bit is a debug mask, so
+ * the counter is only in the remaining bits
+ */
+ unsigned int fin;
+ unsigned int fout;
+ int hangupcause; /*!< Why is the channel hanged up. See causes.h */
+ struct varshead varshead; /*!< A linked list for channel variables */
+ 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;
+ void *unused; /*! This pointer should stay for Asterisk 1.4. It just keeps the struct size the same
+ * for the sake of ABI compatability. */
+
+ 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 */
+
+ int visible_indication; /*!< Indication currently playing on the channel */
+
+ /*! \brief Data stores on the channel */
+ AST_LIST_HEAD_NOLOCK(datastores, ast_datastore) datastores;
+};
+
+/*! \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),
+ /*! This channel is being whispered on */
+ AST_FLAG_WHISPER = (1 << 11),
+ /*! 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),
+ /*! This flag indicates that on a masquerade, an active stream should not
+ * be carried over */
+ AST_FLAG_MASQ_NOSTREAM = (1 << 15),
+ /*! This flag indicates that the hangup exten was run when the bridge terminated,
+ * a message aimed at preventing a subsequent hangup exten being run at the pbx_run
+ * level */
+ AST_FLAG_BRIDGE_HANGUP_RUN = (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_NO_H_EXTEN = (1 << 6),
+};
+
+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;
+ void (* end_bridge_callback)(void *); /*!< A callback that is called after a bridge attempt */
+ void *end_bridge_callback_data; /*!< Data passed to the callback */
+ /*! If the end_bridge_callback_data refers to a channel which no longer is going to
+ * exist when the end_bridge_callback is called, then it needs to be fixed up properly
+ */
+ void (*end_bridge_callback_data_fixup)(struct ast_bridge_config *bconfig, struct ast_channel *originator, struct ast_channel *terminator);
+};
+
+struct chanmon;
+
+#define LOAD_OH(oh) { \
+ oh.context = context; \
+ oh.exten = exten; \
+ oh.priority = priority; \
+ oh.cid_num = cid_num; \
+ oh.cid_name = cid_name; \
+ oh.account = account; \
+ oh.vars = vars; \
+ oh.parent_channel = NULL; \
+}
+
+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 */
+struct ast_datastore *ast_channel_datastore_alloc(const struct ast_datastore_info *info, 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 */
+int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore);
+
+/*! \brief Remove a datastore from a channel */
+int ast_channel_datastore_remove(struct ast_channel *chan, struct ast_datastore *datastore);
+
+/*! \brief Find a datastore on a channel */
+struct ast_datastore *ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, 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
+ \return Returns NULL on failure to allocate.
+ \note New channels are
+ by default set to the "default" context and
+ extension "s"
+ */
+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, ...) __attribute__((format(printf, 9, 10)));
+
+/*! \brief Queue an outgoing frame */
+int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f);
+
+/*!
+ * \brief Queue an outgoing frame to the head of the frame queue
+ *
+ * \param chan the channel to queue the frame on
+ * \param f the frame to queue. Note that this frame will be duplicated by
+ * this function. It is the responsibility of the caller to handle
+ * freeing the memory associated with the frame being passed if
+ * necessary.
+ *
+ * \retval 0 success
+ * \retval non-zero failure
+ */
+int ast_queue_frame_head(struct ast_channel *chan, struct ast_frame *f);
+
+/*! \brief Queue a hangup frame */
+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
+ \return zero on success, 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
+ \return zero on success, non-zero on 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.
+*/
+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 */
+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
+ * \return Returns an ast_channel on success, NULL on failure.
+ */
+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 unsuceessful)
+ * \param cidnum Caller-ID Number
+ * \param cidname Caller-ID Name
+ * \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 *cidnum, const char *cidname);
+
+struct ast_channel *__ast_request_and_dial(const char *type, int format, void *data, int timeout, int *reason, const char *cidnum, const char *cidname, 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
+ * 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.
+ * \param cause Ast hangupcause for hangup
+ * \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 retturn -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).
+ */
+void ast_channel_setwhentohangup(struct ast_channel *chan, time_t offset);
+
+/*! \brief Answer a ringing call
+ * \param chan channel to answer
+ * This function answers a channel and handles all necessary call
+ * setup functions.
+ * \return Returns 0 on success, -1 on failure
+ */
+int ast_answer(struct ast_channel *chan);
+
+/*! \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_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
+ * \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 specied 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 specied 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
+ Read a frame.
+ \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.
+ * Read 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.
+ \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 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 compoent 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
+ * Write text to a display on a channel
+ * \param chan channel to act upon
+ * \param text string of text to send on the channel
+ * \return Returns 0 on success, -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
+ * \return Returns 0 on success, -1 on failure
+ */
+int ast_senddigit(struct ast_channel *chan, char digit);
+
+int ast_senddigit_begin(struct ast_channel *chan, char digit);
+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 (locks channel) */
+struct ast_channel *ast_get_channel_by_name_locked(const char *chan);
+
+/*! \brief Get channel by name prefix (locks channel) */
+struct ast_channel *ast_get_channel_by_name_prefix_locked(const char *name, const int namelen);
+
+/*! \brief Get channel by name 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
+ * \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. */
+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
+ */
+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 capbility
+ */
+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);
+
+/*! Undeos a defer */
+/*! 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);
+
+/*! Deactive an active generator */
+void ast_deactivate_generator(struct ast_channel *chan);
+
+/*!
+ * \note The channel does not need to be locked before calling this function.
+ */
+void ast_set_callerid(struct ast_channel *chan, const char *cidnum, const char *cidname, const char *ani);
+
+
+/*! return a mallocd string with the result of sprintf of the fmt and following args */
+char __attribute__((format(printf, 1, 2))) *ast_safe_string_alloc(const char *fmt, ...);
+
+
+/*! 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...
+ *
+ * \note if chan is locked prior to calling ast_autoservice_stop, it
+ * is likely that there will be a deadlock between the thread that calls
+ * ast_autoservice_stop and the autoservice thread. It is important
+ * that chan is not locked prior to this call
+ *
+ * \retval 0 success
+ * \retval -1 error, or the channel has been hungup
+ */
+int ast_autoservice_stop(struct ast_channel *chan);
+
+/* If built with DAHDI 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 wacked 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
+}
+
+#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); \
+ } 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 Begin 'whispering' onto a channel
+ \param chan The channel to whisper onto
+ \return 0 for success, non-zero for failure
+
+ This function will add a whisper buffer onto a channel and set a flag
+ causing writes to the channel to reduce the volume level of the written
+ audio samples, and then to mix in audio from the whisper buffer if it
+ is available.
+
+ Note: This function performs no locking; you must hold the channel's lock before
+ calling this function.
+ */
+int ast_channel_whisper_start(struct ast_channel *chan);
+
+/*!
+ \brief Feed an audio frame into the whisper buffer on a channel
+ \param chan The channel to whisper onto
+ \param f The frame to to whisper onto chan
+ \return 0 for success, non-zero for failure
+ */
+int ast_channel_whisper_feed(struct ast_channel *chan, struct ast_frame *f);
+
+/*!
+ \brief Stop 'whispering' onto a channel
+ \param chan The channel to whisper onto
+ \return 0 for success, non-zero for failure
+
+ Note: This function performs no locking; you must hold the channel's lock before
+ calling this function.
+ */
+void ast_channel_whisper_stop(struct ast_channel *chan);
+
+
+
+/*!
+ \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
+ */
+char *ast_channel_reason2str(int reason);
+
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _ASTERISK_CHANNEL_H */
diff --git a/include/asterisk/chanvars.h b/include/asterisk/chanvars.h
new file mode 100644
index 000000000..63de58429
--- /dev/null
+++ b/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/include/asterisk/cli.h b/include/asterisk/cli.h
new file mode 100644
index 000000000..13d6fdd84
--- /dev/null
+++ b/include/asterisk/cli.h
@@ -0,0 +1,183 @@
+/*
+ * 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 <stdarg.h>
+
+#include "asterisk/linkedlists.h"
+
+void ast_cli(int fd, char *fmt, ...)
+ __attribute__((format(printf, 2, 3)));
+
+#define RESULT_SUCCESS 0
+#define RESULT_SHOWUSAGE 1
+#define RESULT_FAILURE 2
+
+#define AST_MAX_CMD_LEN 16
+
+#define AST_MAX_ARGS 64
+
+#define AST_CLI_COMPLETE_EOF "_EOF_"
+
+/*! \brief A command line entry */
+struct ast_cli_entry {
+ char * const cmda[AST_MAX_CMD_LEN];
+ /*! Handler for the command (fd for output, # of args, argument list).
+ Returns RESULT_SHOWUSAGE for improper arguments.
+ argv[] has argc 'useful' entries, and an additional NULL entry
+ at the end so that clients requiring NULL terminated arrays
+ can use it without need for copies.
+ You can overwrite argv or the strings it points to, but remember
+ that this memory is deallocated after the handler returns.
+ */
+ int (*handler)(int fd, int argc, char *argv[]);
+ /*! Summary of the command (< 60 characters) */
+ const char *summary;
+ /*! Detailed usage information */
+ const char *usage;
+ /*! Generate the n-th (starting from 0) possible completion
+ for a given 'word' following 'line' in position 'pos'.
+ 'line' and 'word' must not be modified.
+ Must return a malloc'ed string with the n-th value when available,
+ or NULL if the n-th completion does not exist.
+ Typically, the function is called with increasing values for n
+ until a NULL is returned.
+ */
+ char *(*generator)(const char *line, const char *word, int pos, int n);
+ struct ast_cli_entry *deprecate_cmd;
+ /*! For keeping track of usage */
+ int inuse;
+ struct module *module; /*! module this belongs to */
+ char *_full_cmd; /* built at load time from cmda[] */
+ /* 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 deprecated;
+ char *_deprecated_by; /* copied from the "parent" _full_cmd, on deprecated commands */
+ /*! For linking */
+ AST_LIST_ENTRY(ast_cli_entry) list;
+};
+
+/*!
+ * \brief 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
+ * Returns 0 on succes, -1 on failure
+ */
+int ast_cli_command(int fd, const char *s);
+
+/*!
+ * \brief Executes multiple CLI commands
+ * Interpret strings separated by '\0' and execute each one, sending output to fd
+ * \param size is the total size of the 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
+ * Returns 0 on success, -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
+ */
+void 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
+ * Returns 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
+ */
+void ast_cli_unregister_multiple(struct ast_cli_entry *e, int len);
+
+/*! \brief Readline madness
+ * Useful for readline, that's about it
+ * Returns 0 on success, -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, followe 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/include/asterisk/compat.h b/include/asterisk/compat.h
new file mode 100644
index 000000000..22261a390
--- /dev/null
+++ b/include/asterisk/compat.h
@@ -0,0 +1,131 @@
+/*
+ * 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
+ */
+
+#ifndef _COMPAT_H
+#define _COMPAT_H
+
+#include "asterisk/autoconfig.h"
+#include <inttypes.h>
+#include <sys/types.h>
+#include <stdarg.h>
+
+#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
+
+#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;
+typedef unsigned int uint;
+#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/include/asterisk/compiler.h b/include/asterisk/compiler.h
new file mode 100644
index 000000000..618950017
--- /dev/null
+++ b/include/asterisk/compiler.h
@@ -0,0 +1,62 @@
+/*
+ * 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
+
+#ifdef HAVE_ATTRIBUTE_always_inline
+#define force_inline __attribute__((always_inline)) inline
+#else
+#define force_inline inline
+#endif
+
+#ifdef HAVE_ATTRIBUTE_pure
+#define attribute_pure __attribute__((pure))
+#else
+#define attribute_pure
+#endif
+
+#ifdef HAVE_ATTRIBUTE_const
+#define attribute_const __attribute__((const))
+#else
+#define attribute_const
+#endif
+
+#ifdef HAVE_ATTRIBUTE_unused
+#define attribute_unused __attribute__((unused))
+#else
+#define attribute_unused
+#endif
+
+#ifdef HAVE_ATTRIBUTE_malloc
+#define attribute_malloc __attribute__((malloc))
+#else
+#define attribute_malloc
+#endif
+
+#ifdef HAVE_ATTRIBUTE_deprecated
+#define attribute_deprecated __attribute__((deprecated))
+#else
+#define attribute_deprecated
+#endif
+
+#endif /* _ASTERISK_COMPILER_H */
diff --git a/include/asterisk/config.h b/include/asterisk/config.h
new file mode 100644
index 000000000..160636588
--- /dev/null
+++ b/include/asterisk/config.h
@@ -0,0 +1,206 @@
+/*
+ * 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 <stdarg.h>
+
+struct ast_config;
+
+struct ast_category;
+
+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];
+};
+
+typedef struct ast_config *config_load_func(const char *database, const char *table, const char *configfile, struct ast_config *config, int withcomments);
+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);
+
+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;
+ 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.
+ *
+ * Returns NULL on error, or an ast_config data structure on success
+ */
+struct ast_config *ast_config_load(const char *filename);
+struct ast_config *ast_config_load_with_comments(const char *filename);
+
+/*! \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 funtion is kind of non-intuitive in it's use. To begin, one passes NULL as the second arguement. 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.
+ *
+ * Returns a category on success, or 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
+ *
+ * Returns ast_variable list on success, or NULL on failure
+ */
+struct ast_variable *ast_variable_browse(const struct ast_config *config, const char *category);
+
+/*! \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
+ *
+ * Returns the variable value on success, or 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.
+ *
+ * Returns pointer to category if found, 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, ...);
+
+/*! \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 Check if realtime engine is configured for family
+ * returns 1 if family is configured in realtime and engine exists
+ * \param family which family/config to be checked
+*/
+int ast_check_realtime(const char *family);
+
+/*! \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);
+void ast_category_append(struct ast_config *config, struct ast_category *cat);
+int ast_category_delete(struct ast_config *cfg, 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);
+void ast_variable_append(struct ast_category *category, struct ast_variable *variable);
+int ast_variable_delete(struct ast_category *category, char *variable, 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, int withcomments);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _ASTERISK_CONFIG_H */
diff --git a/include/asterisk/crypto.h b/include/asterisk/crypto.h
new file mode 100644
index 000000000..32233fc17
--- /dev/null
+++ b/include/asterisk/crypto.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 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)
+ *
+ * Returns the key on success or 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
+ *
+ * Returns 0 if the signature is valid, or -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
+ *
+ * Returns 0 if the signature is valid, or -1 otherwise
+ *
+ */
+int (*ast_check_signature_bin)(struct ast_key *key, const char *msg, int msglen, const unsigned char *sig);
+
+/*!
+ * \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
+ *
+ * Returns 0 on success or -1 on failure.
+ *
+ */
+int (*ast_sign)(struct ast_key *key, char *msg, char *sig);
+
+/*!
+ * \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
+ *
+ * Returns 0 on success or -1 on failure.
+ *
+ */
+int (*ast_sign_bin)(struct ast_key *key, const char *msg, int msglen, unsigned char *sig);
+
+/*!
+ * \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
+ *
+ * Returns length of encrypted data on success or -1 on failure.
+ *
+ */
+int (*ast_encrypt_bin)(unsigned char *dst, const unsigned char *src, int srclen, struct ast_key *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
+ *
+ * Returns length of decrypted data on success or -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/include/asterisk/dahdi_compat.h b/include/asterisk/dahdi_compat.h
new file mode 100644
index 000000000..a8f602af1
--- /dev/null
+++ b/include/asterisk/dahdi_compat.h
@@ -0,0 +1,458 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2008, 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.
+ */
+
+/*!
+ * \file
+ * \brief DAHDI compatibility with zaptel
+ */
+
+#ifndef DAHDI_COMPAT_H
+#define DAHDI_COMPAT_H
+
+#if defined(HAVE_DAHDI)
+
+#include <dahdi/user.h>
+
+#define DAHDI_DIR_NAME "/dev/dahdi"
+#define DAHDI_NAME "DAHDI"
+
+#elif defined(HAVE_ZAPTEL)
+
+#include <zaptel/zaptel.h>
+
+#define DAHDI_DIR_NAME "/dev/zap"
+#define DAHDI_NAME "DAHDI"
+
+/* Compiling against Zaptel instead of DAHDI */
+
+#if defined(__ZT_SIG_FXO)
+#define __DAHDI_SIG_FXO __ZT_SIG_FXO
+#endif
+#if defined(__ZT_SIG_FXS)
+#define __DAHDI_SIG_FXS __ZT_SIG_FXS
+#endif
+#if defined(ZT_ALARM_BLUE)
+#define DAHDI_ALARM_BLUE ZT_ALARM_BLUE
+#endif
+#if defined(ZT_ALARM_LOOPBACK)
+#define DAHDI_ALARM_LOOPBACK ZT_ALARM_LOOPBACK
+#endif
+#if defined(ZT_ALARM_NONE)
+#define DAHDI_ALARM_NONE ZT_ALARM_NONE
+#endif
+#if defined(ZT_ALARM_NOTOPEN)
+#define DAHDI_ALARM_NOTOPEN ZT_ALARM_NOTOPEN
+#endif
+#if defined(ZT_ALARM_RECOVER)
+#define DAHDI_ALARM_RECOVER ZT_ALARM_RECOVER
+#endif
+#if defined(ZT_ALARM_RED)
+#define DAHDI_ALARM_RED ZT_ALARM_RED
+#endif
+#if defined(ZT_ALARM_YELLOW)
+#define DAHDI_ALARM_YELLOW ZT_ALARM_YELLOW
+#endif
+#if defined(ZT_AUDIOMODE)
+#define DAHDI_AUDIOMODE ZT_AUDIOMODE
+#endif
+#if defined(ZT_CHANNO)
+#define DAHDI_CHANNO ZT_CHANNO
+#endif
+#if defined(ZT_CHECK_HOOKSTATE)
+#define DAHDI_CHECK_HOOKSTATE ZT_CHECK_HOOKSTATE
+#endif
+#if defined(ZT_CONF_CONF)
+#define DAHDI_CONF_CONF ZT_CONF_CONF
+#endif
+#if defined(ZT_CONF_CONFANN)
+#define DAHDI_CONF_CONFANN ZT_CONF_CONFANN
+#endif
+#if defined(ZT_CONF_CONFANNMON)
+#define DAHDI_CONF_CONFANNMON ZT_CONF_CONFANNMON
+#endif
+#if defined(ZT_CONF_CONFMON)
+#define DAHDI_CONF_CONFMON ZT_CONF_CONFMON
+#endif
+#if defined(ZT_CONF_DIGITALMON)
+#define DAHDI_CONF_DIGITALMON ZT_CONF_DIGITALMON
+#endif
+#if defined(ZT_CONF_LISTENER)
+#define DAHDI_CONF_LISTENER ZT_CONF_LISTENER
+#endif
+#if defined(ZT_CONF_MONITORBOTH)
+#define DAHDI_CONF_MONITORBOTH ZT_CONF_MONITORBOTH
+#endif
+#if defined(ZT_CONF_NORMAL)
+#define DAHDI_CONF_NORMAL ZT_CONF_NORMAL
+#endif
+#if defined(ZT_CONF_PSEUDO_LISTENER)
+#define DAHDI_CONF_PSEUDO_LISTENER ZT_CONF_PSEUDO_LISTENER
+#endif
+#if defined(ZT_CONF_PSEUDO_TALKER)
+#define DAHDI_CONF_PSEUDO_TALKER ZT_CONF_PSEUDO_TALKER
+#endif
+#if defined(ZT_CONF_REALANDPSEUDO)
+#define DAHDI_CONF_REALANDPSEUDO ZT_CONF_REALANDPSEUDO
+#endif
+#if defined(ZT_CONF_TALKER)
+#define DAHDI_CONF_TALKER ZT_CONF_TALKER
+#endif
+#if defined(ZT_CONFDIAG)
+#define DAHDI_CONFDIAG ZT_CONFDIAG
+#endif
+#if defined(ZT_CONFMUTE)
+#define DAHDI_CONFMUTE ZT_CONFMUTE
+#endif
+#if defined(ZT_DEFAULT_NUM_BUFS)
+#define DAHDI_DEFAULT_NUM_BUFS ZT_DEFAULT_NUM_BUFS
+#endif
+#if defined(ZT_DIAL)
+#define DAHDI_DIAL ZT_DIAL
+#endif
+#if defined(ZT_DIALING)
+#define DAHDI_DIALING ZT_DIALING
+#endif
+#if defined(ZT_DIAL_OP_APPEND)
+#define DAHDI_DIAL_OP_APPEND ZT_DIAL_OP_APPEND
+#endif
+#if defined(ZT_DIAL_OP_REPLACE)
+#define DAHDI_DIAL_OP_REPLACE ZT_DIAL_OP_REPLACE
+#endif
+#if defined(ZT_ECHOCANCEL)
+#define DAHDI_ECHOCANCEL ZT_ECHOCANCEL
+#endif
+#if defined(ZT_ECHOTRAIN)
+#define DAHDI_ECHOTRAIN ZT_ECHOTRAIN
+#endif
+#if defined(ZT_EVENT_ALARM)
+#define DAHDI_EVENT_ALARM ZT_EVENT_ALARM
+#endif
+#if defined(ZT_EVENT_BITSCHANGED)
+#define DAHDI_EVENT_BITSCHANGED ZT_EVENT_BITSCHANGED
+#endif
+#if defined(ZT_EVENT_DIALCOMPLETE)
+#define DAHDI_EVENT_DIALCOMPLETE ZT_EVENT_DIALCOMPLETE
+#endif
+#if defined(ZT_EVENT_DTMFDOWN)
+#define DAHDI_EVENT_DTMFDOWN ZT_EVENT_DTMFDOWN
+#endif
+#if defined(ZT_EVENT_DTMFUP)
+#define DAHDI_EVENT_DTMFUP ZT_EVENT_DTMFUP
+#endif
+#if defined(ZT_EVENT_EC_DISABLED)
+#define DAHDI_EVENT_EC_DISABLED ZT_EVENT_EC_DISABLED
+#endif
+#if defined(ZT_EVENT_HOOKCOMPLETE)
+#define DAHDI_EVENT_HOOKCOMPLETE ZT_EVENT_HOOKCOMPLETE
+#endif
+#if defined(ZT_EVENT_NOALARM)
+#define DAHDI_EVENT_NOALARM ZT_EVENT_NOALARM
+#endif
+#if defined(ZT_EVENT_NONE)
+#define DAHDI_EVENT_NONE ZT_EVENT_NONE
+#endif
+#if defined(ZT_EVENT_ONHOOK)
+#define DAHDI_EVENT_ONHOOK ZT_EVENT_ONHOOK
+#endif
+#if defined(ZT_EVENT_POLARITY)
+#define DAHDI_EVENT_POLARITY ZT_EVENT_POLARITY
+#endif
+#if defined(ZT_EVENT_PULSEDIGIT)
+#define DAHDI_EVENT_PULSEDIGIT ZT_EVENT_PULSEDIGIT
+#endif
+#if defined(ZT_EVENT_PULSE_START)
+#define DAHDI_EVENT_PULSE_START ZT_EVENT_PULSE_START
+#endif
+#if defined(ZT_EVENT_REMOVED)
+#define DAHDI_EVENT_REMOVED ZT_EVENT_REMOVED
+#endif
+#if defined(ZT_EVENT_RINGBEGIN)
+#define DAHDI_EVENT_RINGBEGIN ZT_EVENT_RINGBEGIN
+#endif
+#if defined(ZT_EVENT_RINGEROFF)
+#define DAHDI_EVENT_RINGEROFF ZT_EVENT_RINGEROFF
+#endif
+#if defined(ZT_EVENT_RINGERON)
+#define DAHDI_EVENT_RINGERON ZT_EVENT_RINGERON
+#endif
+#if defined(ZT_EVENT_RINGOFFHOOK)
+#define DAHDI_EVENT_RINGOFFHOOK ZT_EVENT_RINGOFFHOOK
+#endif
+#if defined(ZT_EVENT_TIMER_EXPIRED)
+#define DAHDI_EVENT_TIMER_EXPIRED ZT_EVENT_TIMER_EXPIRED
+#endif
+#if defined(ZT_EVENT_TIMER_PING)
+#define DAHDI_EVENT_TIMER_PING ZT_EVENT_TIMER_PING
+#endif
+#if defined(ZT_EVENT_WINKFLASH)
+#define DAHDI_EVENT_WINKFLASH ZT_EVENT_WINKFLASH
+#endif
+#if defined(ZT_FLASH)
+#define DAHDI_FLASH ZT_FLASH
+#endif
+#if defined(ZT_FLUSH)
+#define DAHDI_FLUSH ZT_FLUSH
+#endif
+#if defined(ZT_FLUSH_ALL)
+#define DAHDI_FLUSH_ALL ZT_FLUSH_ALL
+#endif
+#if defined(ZT_FLUSH_BOTH)
+#define DAHDI_FLUSH_BOTH ZT_FLUSH_BOTH
+#endif
+#if defined(ZT_FLUSH_READ)
+#define DAHDI_FLUSH_READ ZT_FLUSH_READ
+#endif
+#if defined(ZT_FLUSH_WRITE)
+#define DAHDI_FLUSH_WRITE ZT_FLUSH_WRITE
+#endif
+#if defined(ZT_GET_BUFINFO)
+#define DAHDI_GET_BUFINFO ZT_GET_BUFINFO
+#endif
+#if defined(ZT_GETCONF)
+#define DAHDI_GETCONF ZT_GETCONF
+#endif
+#if defined(ZT_GETCONFMUTE)
+#define DAHDI_GETCONFMUTE ZT_GETCONFMUTE
+#endif
+#if defined(ZT_GETEVENT)
+#define DAHDI_GETEVENT ZT_GETEVENT
+#endif
+#if defined(ZT_GETGAINS)
+#define DAHDI_GETGAINS ZT_GETGAINS
+#endif
+#if defined(ZT_GET_PARAMS)
+#define DAHDI_GET_PARAMS ZT_GET_PARAMS
+#endif
+#if defined(ZT_HOOK)
+#define DAHDI_HOOK ZT_HOOK
+#endif
+#if defined(ZT_IOMUX)
+#define DAHDI_IOMUX ZT_IOMUX
+#endif
+#if defined(ZT_IOMUX_READ)
+#define DAHDI_IOMUX_READ ZT_IOMUX_READ
+#endif
+#if defined(ZT_IOMUX_SIGEVENT)
+#define DAHDI_IOMUX_SIGEVENT ZT_IOMUX_SIGEVENT
+#endif
+#if defined(ZT_IOMUX_WRITE)
+#define DAHDI_IOMUX_WRITE ZT_IOMUX_WRITE
+#endif
+#if defined(ZT_LAW_ALAW)
+#define DAHDI_LAW_ALAW ZT_LAW_ALAW
+#endif
+#if defined(ZT_LAW_DEFAULT)
+#define DAHDI_LAW_DEFAULT ZT_LAW_DEFAULT
+#endif
+#if defined(ZT_LAW_MULAW)
+#define DAHDI_LAW_MULAW ZT_LAW_MULAW
+#endif
+#if defined(ZT_MAX_NUM_BUFS)
+#define DAHDI_MAX_NUM_BUFS ZT_MAX_NUM_BUFS
+#endif
+#if defined(ZT_MAX_SPANS)
+#define DAHDI_MAX_SPANS ZT_MAX_SPANS
+#endif
+#if defined(ZT_OFFHOOK)
+#define DAHDI_OFFHOOK ZT_OFFHOOK
+#endif
+#if defined(ZT_ONHOOK)
+#define DAHDI_ONHOOK ZT_ONHOOK
+#endif
+#if defined(ZT_ONHOOKTRANSFER)
+#define DAHDI_ONHOOKTRANSFER ZT_ONHOOKTRANSFER
+#endif
+#if defined(ZT_POLICY_IMMEDIATE)
+#define DAHDI_POLICY_IMMEDIATE ZT_POLICY_IMMEDIATE
+#endif
+#if defined(ZT_POLICY_WHEN_FULL)
+#define DAHDI_POLICY_WHEN_FULL ZT_POLICY_WHEN_FULL
+#endif
+#if defined(ZT_RING)
+#define DAHDI_RING ZT_RING
+#endif
+#if defined(ZT_RINGOFF)
+#define DAHDI_RINGOFF ZT_RINGOFF
+#endif
+#if defined(ZT_SENDTONE)
+#define DAHDI_SENDTONE ZT_SENDTONE
+#endif
+#if defined(ZT_SET_BLOCKSIZE)
+#define DAHDI_SET_BLOCKSIZE ZT_SET_BLOCKSIZE
+#endif
+#if defined(ZT_SET_BUFINFO)
+#define DAHDI_SET_BUFINFO ZT_SET_BUFINFO
+#endif
+#if defined(ZT_SETCADENCE)
+#define DAHDI_SETCADENCE ZT_SETCADENCE
+#endif
+#if defined(ZT_SETCONF)
+#define DAHDI_SETCONF ZT_SETCONF
+#endif
+#if defined(ZT_SET_DIALPARAMS)
+#define DAHDI_SET_DIALPARAMS ZT_SET_DIALPARAMS
+#endif
+#if defined(ZT_SETGAINS)
+#define DAHDI_SETGAINS ZT_SETGAINS
+#endif
+#if defined(ZT_SETLAW)
+#define DAHDI_SETLAW ZT_SETLAW
+#endif
+#if defined(ZT_SETLINEAR)
+#define DAHDI_SETLINEAR ZT_SETLINEAR
+#endif
+#if defined(ZT_SET_PARAMS)
+#define DAHDI_SET_PARAMS ZT_SET_PARAMS
+#endif
+#if defined(ZT_SETTONEZONE)
+#define DAHDI_SETTONEZONE ZT_SETTONEZONE
+#endif
+#if defined(ZT_SIG_CLEAR)
+#define DAHDI_SIG_CLEAR ZT_SIG_CLEAR
+#endif
+#if defined(ZT_SIG_EM)
+#define DAHDI_SIG_EM ZT_SIG_EM
+#endif
+#if defined(ZT_SIG_EM_E1)
+#define DAHDI_SIG_EM_E1 ZT_SIG_EM_E1
+#endif
+#if defined(ZT_SIG_FXO)
+#define DAHDI_SIG_FXO ZT_SIG_FXO
+#endif
+#if defined(ZT_SIG_FXOGS)
+#define DAHDI_SIG_FXOGS ZT_SIG_FXOGS
+#endif
+#if defined(ZT_SIG_FXOKS)
+#define DAHDI_SIG_FXOKS ZT_SIG_FXOKS
+#endif
+#if defined(ZT_SIG_FXOLS)
+#define DAHDI_SIG_FXOLS ZT_SIG_FXOLS
+#endif
+#if defined(ZT_SIG_FXS)
+#define DAHDI_SIG_FXS ZT_SIG_FXS
+#endif
+#if defined(ZT_SIG_FXSGS)
+#define DAHDI_SIG_FXSGS ZT_SIG_FXSGS
+#endif
+#if defined(ZT_SIG_FXSKS)
+#define DAHDI_SIG_FXSKS ZT_SIG_FXSKS
+#endif
+#if defined(ZT_SIG_FXSLS)
+#define DAHDI_SIG_FXSLS ZT_SIG_FXSLS
+#endif
+#if defined(ZT_SIG_HARDHDLC)
+#define DAHDI_SIG_HARDHDLC ZT_SIG_HARDHDLC
+#endif
+#if defined(ZT_SIG_HDLCFCS)
+#define DAHDI_SIG_HDLCFCS ZT_SIG_HDLCFCS
+#endif
+#if defined(ZT_SIG_SF)
+#define DAHDI_SIG_SF ZT_SIG_SF
+#endif
+#if defined(ZT_SPANSTAT)
+#define DAHDI_SPANSTAT ZT_SPANSTAT
+#endif
+#if defined(ZT_SPECIFY)
+#define DAHDI_SPECIFY ZT_SPECIFY
+#endif
+#if defined(ZT_START)
+#define DAHDI_START ZT_START
+#endif
+#if defined(ZT_TC_ALLOCATE)
+#define DAHDI_TC_ALLOCATE ZT_TC_ALLOCATE
+#endif
+#if defined(ZT_TC_GETINFO)
+#define DAHDI_TC_GETINFO ZT_TC_GETINFO
+#endif
+#if defined(ZT_TIMERACK)
+#define DAHDI_TIMERACK ZT_TIMERACK
+#endif
+#if defined(ZT_TIMERCONFIG)
+#define DAHDI_TIMERCONFIG ZT_TIMERCONFIG
+#endif
+#if defined(ZT_TIMERPING)
+#define DAHDI_TIMERPING ZT_TIMERPING
+#endif
+#if defined(ZT_TIMERPONG)
+#define DAHDI_TIMERPONG ZT_TIMERPONG
+#endif
+#if defined(ZT_TONE_BUSY)
+#define DAHDI_TONE_BUSY ZT_TONE_BUSY
+#endif
+#if defined(ZT_TONE_CONGESTION)
+#define DAHDI_TONE_CONGESTION ZT_TONE_CONGESTION
+#endif
+#if defined(ZT_TONEDETECT)
+#define DAHDI_TONEDETECT ZT_TONEDETECT
+#endif
+#if defined(ZT_TONEDETECT_MUTE)
+#define DAHDI_TONEDETECT_MUTE ZT_TONEDETECT_MUTE
+#endif
+#if defined(ZT_TONEDETECT_ON)
+#define DAHDI_TONEDETECT_ON ZT_TONEDETECT_ON
+#endif
+#if defined(ZT_TONE_DIALRECALL)
+#define DAHDI_TONE_DIALRECALL ZT_TONE_DIALRECALL
+#endif
+#if defined(ZT_TONE_DIALTONE)
+#define DAHDI_TONE_DIALTONE ZT_TONE_DIALTONE
+#endif
+#if defined(ZT_TONE_DTMF_BASE)
+#define DAHDI_TONE_DTMF_BASE ZT_TONE_DTMF_BASE
+#endif
+#if defined(ZT_TONE_INFO)
+#define DAHDI_TONE_INFO ZT_TONE_INFO
+#endif
+#if defined(ZT_TONE_RINGTONE)
+#define DAHDI_TONE_RINGTONE ZT_TONE_RINGTONE
+#endif
+#if defined(ZT_TONE_STUTTER)
+#define DAHDI_TONE_STUTTER ZT_TONE_STUTTER
+#endif
+#if defined(ZT_vldtmf)
+#define DAHDI_vldtmf ZT_vldtmf
+#endif
+#if defined(ZT_WINK)
+#define DAHDI_WINK ZT_WINK
+#endif
+#if defined(HAVE_ZAPTEL)
+#define HAVE_DAHDI HAVE_ZAPTEL
+#endif
+
+#define DAHDI_TONE_DTMF_A ZT_TONE_DTMF_A
+#define DAHDI_TONE_DTMF_p ZT_TONE_DTMF_p
+#define DAHDI_TONE_DTMF_s ZT_TONE_DTMF_s
+
+#define dahdi_bufferinfo zt_bufferinfo
+#define dahdi_confinfo zt_confinfo
+#define dahdi_dialoperation zt_dialoperation
+#define dahdi_dialparams zt_dialparams
+#define dahdi_gains zt_gains
+#define dahdi_params zt_params
+#define dahdi_ring_cadence zt_ring_cadence
+#define dahdi_spaninfo zt_spaninfo
+#define dahdi_transcoder_info zt_transcoder_info
+#define dahdi_transcoder_formats zt_transcoder_formats
+
+#endif
+
+#define DAHDI_FILE_CHANNEL DAHDI_DIR_NAME "/channel"
+#define DAHDI_FILE_CTL DAHDI_DIR_NAME "/ctl"
+#define DAHDI_FILE_PSEUDO DAHDI_DIR_NAME "/pseudo"
+#define DAHDI_FILE_TIMER DAHDI_DIR_NAME "/timer"
+#define DAHDI_FILE_TRANSCODE DAHDI_DIR_NAME "/transcode"
+
+#endif /* DAHDI_COMPAT_H */
diff --git a/include/asterisk/devicestate.h b/include/asterisk/devicestate.h
new file mode 100644
index 000000000..561bd2cb4
--- /dev/null
+++ b/include/asterisk/devicestate.h
@@ -0,0 +1,133 @@
+/*
+ * 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
+ */
+
+#ifndef _ASTERISK_DEVICESTATE_H
+#define _ASTERISK_DEVICESTATE_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/*! Device is valid but channel didn't know state */
+#define AST_DEVICE_UNKNOWN 0
+/*! Device is not used */
+#define AST_DEVICE_NOT_INUSE 1
+/*! Device is in use */
+#define AST_DEVICE_INUSE 2
+/*! Device is busy */
+#define AST_DEVICE_BUSY 3
+/*! Device is invalid */
+#define AST_DEVICE_INVALID 4
+/*! Device is unavailable */
+#define AST_DEVICE_UNAVAILABLE 5
+/*! Device is ringing */
+#define AST_DEVICE_RINGING 6
+/*! Device is ringing *and* in use */
+#define AST_DEVICE_RINGINUSE 7
+/*! Device is on hold */
+#define AST_DEVICE_ONHOLD 8
+
+/*! \brief Devicestate watcher call back */
+typedef int (*ast_devstate_cb_type)(const char *dev, int state, void *data);
+
+/*! \brief Devicestate provider call back */
+typedef int (*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(int devstate);
+
+/*! \brief Search the Channels by Name
+ * \param device like a dialstring
+ * Search the Device in active channels by compare the channelname against
+ * the devicename. Compared are only the first chars to the first '-' char.
+ * Returns an AST_DEVICE_UNKNOWN if no channel found or
+ * AST_DEVICE_INUSE if a channel is found
+ */
+int ast_parse_device_state(const char *device);
+
+/*! \brief Asks a channel for device state
+ * \param device like a dialstring
+ * Asks a channel for device state, data is normaly a number from dialstring
+ * used by the low level module
+ * Trys the channel devicestate callback if not supported search in the
+ * active channels list for the device.
+ * Returns an AST_DEVICE_??? state -1 on failure
+ */
+int ast_device_state(const char *device);
+
+/*! \brief Tells Asterisk the State for Device is changed
+ * \param fmt devicename like a dialstring with format parameters
+ * Asterisk polls the new extensionstates and calls the registered
+ * callbacks for the changed extensions
+ * Returns 0 on success, -1 on failure
+ */
+int ast_device_state_changed(const char *fmt, ...)
+ __attribute__((format(printf, 1, 2)));
+
+
+/*! \brief Tells Asterisk the State for Device is changed
+ * \param device devicename like a dialstring
+ * Asterisk polls the new extensionstates and calls the registered
+ * callbacks for the changed extensions
+ * Returns 0 on success, -1 on failure
+ */
+int ast_device_state_changed_literal(const char *device);
+
+/*! \brief Registers a device state change callback
+ * \param callback Callback
+ * \param data to pass to callback
+ * The callback is called if the state for extension is changed
+ * Return -1 on failure, ID on success
+ */
+int ast_devstate_add(ast_devstate_cb_type callback, void *data);
+
+/*! \brief Unregisters a device state change callback
+ * \param callback Callback
+ * \param data to pass to callback
+ * The callback is called if the state for extension is changed
+ * Return -1 on failure, ID on success
+ */
+void ast_devstate_del(ast_devstate_cb_type callback, void *data);
+
+/*! \brief Add device state provider
+ * \param label to use in hint, like label:object
+ * \param callback Callback
+ * \retval -1 failure
+ * \retval 0 success
+ */
+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
+ * \return nothing
+ */
+void ast_devstate_prov_del(const char *label);
+
+int ast_device_state_engine_init(void);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _ASTERISK_DEVICESTATE_H */
diff --git a/include/asterisk/dial.h b/include/asterisk/dial.h
new file mode 100644
index 000000000..525f425a0
--- /dev/null
+++ b/include/asterisk/dial.h
@@ -0,0 +1,151 @@
+/*
+ * 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_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);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _ASTERISK_DIAL_H */
diff --git a/include/asterisk/dns.h b/include/asterisk/dns.h
new file mode 100644
index 000000000..64cf68c10
--- /dev/null
+++ b/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/include/asterisk/dnsmgr.h b/include/asterisk/dnsmgr.h
new file mode 100644
index 000000000..c9061dc42
--- /dev/null
+++ b/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 <netinet/in.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/include/asterisk/doxyref.h b/include/asterisk/doxyref.h
new file mode 100644
index 000000000..a64df7210
--- /dev/null
+++ b/include/asterisk/doxyref.h
@@ -0,0 +1,580 @@
+/*
+ * 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 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 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 DataStores
+ * \arg \ref ConfigFiles
+ * \arg \ref SoundFiles included in the Asterisk distribution
+ * \arg \ref AstCREDITS : A Thank You to contributors
+ \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
+ * \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 Global channel variables
+ * \section globchan Global Channel Variables
+ * \verbinclude channelvariables.txt
+ */
+
+/*! \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
+ */
+
+/*! \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.conf
+ * \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 chan_dahdi.conf
+ * \arg Implemented in \ref chan_zap.c
+ * \verbinclude chan_dahdi.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
+ * \verbinclude h323.txt
+ */
+
+/*! \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 (see \ref Config_mod "Modules Configuration"). Each loaded CDR driver produce a billing record for each call.
+ * \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 (see \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 \ref ast_register_application() and unregister with 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
+ * \verbinclude ajam.txt
+ */
+
+/*!
+ * \page Licensing Asterisk Licensing Information
+ *
+ * \section license Asterisk License
+ * \verbinclude LICENSE
+ *
+ * \section otherlicenses Licensing of 3rd Party Code
+ *
+ * This section contains a (not yet complete) list of libraries that are used
+ * by various parts of Asterisk, including related licensing information.
+ *
+ * \subsection alsa_lib ALSA Library
+ * \arg <b>Library</b>: libasound
+ * \arg <b>Website</b>: http://www.alsa-project.org
+ * \arg <b>Used by</b>: chan_alsa
+ * \arg <b>License</b>: LGPL
+ *
+ * \subsection openssl_lib OpenSSL
+ * \arg <b>Library</b>: libcrypto, libssl
+ * \arg <b>Website</b>: http://www.openssl.org
+ * \arg <b>Used by</b>: Asterisk core (TLS for manager and HTTP), res_crypto
+ * \arg <b>License</b>: Apache 2.0
+ * \arg <b>Note</b>: An exception has been granted to allow linking of
+ * OpenSSL with Asterisk.
+ *
+ * \subsection curl_lib Curl
+ * \arg <b>Library</b>: libcurl
+ * \arg <b>Website</b>: http://curl.haxx.se
+ * \arg <b>Used by</b>: func_curl
+ * \arg <b>License</b>: BSD
+ *
+ * \subsection rawlist Raw list of libraries that used by any part of Asterisk
+ * \li c-client.a (app_voicemail with IMAP support)
+ * \li libasound.so.2
+ * \li libc.so.6
+ * \li libcom_err.so.2
+ * \li libcrypt.so.1
+ * \li libcrypto.so.0.9.8 (chan_h323)
+ * \li libcurl.so.4
+ * \li libdl.so.2
+ * \li libexpat.so (chan_h323)
+ * \li libgcc_s.so (chan_h323)
+ * \li libgcrypt.so.11 (chan_h323)
+ * \li libgnutls.so.13 (chan_h323)
+ * \li libgpg-error.so.0 (chan_h323)
+ * \li libgssapi_krb5.so.2
+ * \li libidn.so.11
+ * \li libiksemel.so.3
+ * \li libisdnnet.so
+ * \li libk5crypto.so.3
+ * \li libkeyutils.so.1
+ * \li libkrb5.so.3
+ * \li libkrb5support.so.0
+ * \li liblber-2.4.so.2 (chan_h323)
+ * \li libldap_r-2.4.so.2 (chan_h323)
+ * \li libltdl.so.3
+ * \li libm.so.6
+ * \li libmISDN.so
+ * \li libnbs.so.1
+ * \li libncurses.so.5
+ * \li libnetsnmp.so.15
+ * \li libnetsnmpagent.so.15
+ * \li libnetsnmphelpers.so.15
+ * \li libnetsnmpmibs.so.15
+ * \li libnsl.so.1
+ * \li libodbc.so.1
+ * \li libogg.so.0
+ * \li libopenh323.so (chan_h323)
+ * \li libperl.so.5.8
+ * \li libpq.so.5
+ * \li libpri.so.1.4
+ * \li libpt.so (chan_h323)
+ * \li libpthread.so.0
+ * \li libradiusclient-ng.so.2
+ * \li libresolv.so.2 (chan_h323)
+ * \li libsasl2.so.2 (chan_h323)
+ * \li libsensors.so.3
+ * \li libspeex.so.1
+ * \li libsqlite.so.0
+ * \li libssl.so.0.9.8 (chan_h323)
+ * \li libstdc++.so (chan_h323, chan_vpb)
+ * \li libsuppserv.so
+ * \li libsysfs.so.2
+ * \li libtasn1.so.3 (chan_h323)
+ * \li libtds.so.4
+ * \li libtonezone.so.1.0
+ * \li libvorbis.so.0
+ * \li libvorbisenc.so.2
+ * \li libvpb.a (chan_vpb)
+ * \li libwrap.so.0
+ * \li libz.so.1 (chan_h323)
+ */
diff --git a/include/asterisk/dsp.h b/include/asterisk/dsp.h
new file mode 100644
index 000000000..ccc484c14
--- /dev/null
+++ b/include/asterisk/dsp.h
@@ -0,0 +1,124 @@
+/*
+ * 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);
+
+/*!
+ * \brief Hint that a frame from a dsp was freed
+ *
+ * This is called from ast_frame_free if AST_FRFLAG_FROM_DSP is set. This occurs
+ * because it is possible for the dsp to be freed while someone still holds a reference
+ * to the frame that is in that dsp. This has been known to happen when the dsp on a Zap
+ * channel detects a busy signal. The channel is hung up, and the application that read the
+ * frame to begin with still has a reference to the frame.
+ *
+ * \return nothing
+ */
+void ast_dsp_frame_freed(struct ast_frame *fr);
+
+#endif /* _ASTERISK_DSP_H */
diff --git a/include/asterisk/dundi.h b/include/asterisk/dundi.h
new file mode 100644
index 000000000..09dcea9ee
--- /dev/null
+++ b/include/asterisk/dundi.h
@@ -0,0 +1,226 @@
+/*
+ * 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 \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 (or e164 if unspecified) using the given callerid (if specified) and return up to maxret results in the array specified.
+ returns the number of results found or -1 on a hangup of teh 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/include/asterisk/endian.h b/include/asterisk/endian.h
new file mode 100644
index 000000000..98bff15a2
--- /dev/null
+++ b/include/asterisk/endian.h
@@ -0,0 +1,62 @@
+/*
+ * 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
+ */
+
+#include "asterisk/compat.h"
+
+#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
+#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/include/asterisk/enum.h b/include/asterisk/enum.h
new file mode 100644
index 000000000..c2fe3b592
--- /dev/null
+++ b/include/asterisk/enum.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 enum.h
+ \brief DNS and ENUM functions
+*/
+
+#ifndef _ASTERISK_ENUM_H
+#define _ASTERISK_ENUM_H
+
+#include "asterisk/channel.h"
+
+/*! \brief Lookup entry in ENUM Returns 1 if found, 0 if not found, -1 on hangup
+ \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
+*/
+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);
+
+/*! \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/include/asterisk/features.h b/include/asterisk/features.h
new file mode 100644
index 000000000..c67bd0380
--- /dev/null
+++ b/include/asterisk/features.h
@@ -0,0 +1,101 @@
+/*
+ * 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
+
+#include "asterisk/linkedlists.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 */
+
+#define PARK_APP_NAME "Park"
+
+/*! \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
+ 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)
+ \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
+*/
+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
+ Masquerade the channel rchan into a new, empty channel which is then
+ parked with ast_park_call
+ \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
+*/
+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 */
+char *ast_parking_ext(void);
+
+/*! \brief Determine system call pickup extension */
+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);
+
+#endif /* _AST_FEATURES_H */
diff --git a/include/asterisk/file.h b/include/asterisk/file.h
new file mode 100644
index 000000000..52b0a9f18
--- /dev/null
+++ b/include/asterisk/file.h
@@ -0,0 +1,434 @@
+/*
+ * 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.
+ */
+
+#ifndef _ASTERISK_FILE_H
+#define _ASTERISK_FILE_H
+
+#ifndef stdin
+#error You must include stdio.h before file.h!
+#endif /* !stdin */
+
+#include "asterisk/channel.h"
+#include "asterisk/frame.h"
+#include <fcntl.h>
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+
+/*! Convenient for waiting */
+#define AST_DIGIT_ANY "0123456789#*ABCD"
+#define AST_DIGIT_ANYNUM "0123456789"
+
+/*! structure used for lock and refcount of format handlers.
+ * Should not be here, but this is a temporary workaround
+ * until we implement a more general mechanism.
+ * The format handler should include a pointer to
+ * this structure.
+ * As a trick, if usecnt is initialized with -1,
+ * ast_format_register will init the mutex for you.
+ */
+struct ast_format_lock {
+ ast_mutex_t lock;
+ int usecnt; /* number of active clients */
+};
+
+/*!
+ * Each supported file format is described by the following fields.
+ * 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) */
+ /*! 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);
+ /*! 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;
+};
+
+/*
+ * 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; */
+ /* pointer to private buffer */
+ union {
+ void *_private;
+#if !defined(__cplusplus) && !defined(c_plusplus)
+ void *private attribute_deprecated;
+#endif
+ };
+ const char *orig_chan_name;
+};
+
+#define SEEK_FORCECUR 10
+
+/*! Register a new file format capability
+ * Adds a format to Asterisk's format abilities.
+ * returns 0 on success, -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)
+
+/*! 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.
+ * Returns 0 on success, -1 on failure to unregister
+ */
+int ast_format_unregister(const char *name);
+
+/*! 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.
+ * Returns 0 on success, or -1 on failure.
+ */
+int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang);
+
+/*
+ * if the file name is non-empty, try to play it.
+ * Return 0 if success, -1 if error, digit if interrupted by a digit.
+ * If digits == "" then we can simply check for non-zero.
+ */
+int ast_stream_and_wait(struct ast_channel *chan, const char *file,
+ const char *language, 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);
+
+/*! 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.
+ * Returns -1 if file does not exist, non-zero positive otherwise.
+ */
+int ast_fileexists(const char *filename, const char *fmt, const char *preflang);
+
+/*! 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
+ * Returns -1 on failure
+ */
+int ast_filerename(const char *oldname, const char *newname, const char *fmt);
+
+/*! 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);
+
+/*! 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);
+
+/*! 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, Returns 0
+ * if the stream finishes, the character if it was interrupted, and -1 on error
+ */
+int ast_waitstream(struct ast_channel *c, const char *breakon);
+
+/*! 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, Returns 0
+ * if the stream finishes, the character if it was interrupted, and -1 on error
+ */
+int ast_waitstream_exten(struct ast_channel *c, const char *context);
+
+/*! 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, Returns 0
+ * if the stream finishes, the character if it was interrupted, and -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. Returns
+ 1 if monfd is ready for reading */
+int ast_waitstream_full(struct ast_channel *c, const char *breakon, int audiofd, int monfd);
+
+/*! 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.
+ * Returns a struct ast_filestream on success, NULL on failure
+ */
+struct ast_filestream *ast_readfile(const char *filename, const char *type, const char *comment, int flags, int check, mode_t mode);
+
+/*! 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.
+ * Returns a struct ast_filestream on success, NULL on failure
+ */
+struct ast_filestream *ast_writefile(const char *filename, const char *type, const char *comment, int flags, int check, mode_t mode);
+
+/*! 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
+ * Returns 0 on success, -1 on failure.
+ */
+int ast_writestream(struct ast_filestream *fs, struct ast_frame *f);
+
+/*! Closes a stream */
+/*!
+ * \param f filestream to close
+ * Close a playback or recording stream
+ * Returns 0 on success, -1 on failure
+ */
+int ast_closestream(struct ast_filestream *f);
+
+/*! Opens stream for use in seeking, playing */
+/*!
+ * \param chan channel to work with
+ * \param filename to use
+ * \param preflang prefered language to use
+ * Returns a ast_filestream pointer if it opens the file, NULL on error
+ */
+struct ast_filestream *ast_openstream(struct ast_channel *chan, const char *filename, const char *preflang);
+
+/*! 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
+ * Returns a ast_filestream pointer if it opens the file, NULL on error
+ */
+struct ast_filestream *ast_openstream_full(struct ast_channel *chan, const char *filename, const char *preflang, int asis);
+/*! Opens stream for use in seeking, playing */
+/*!
+ * \param chan channel to work with
+ * \param filename to use
+ * \param preflang prefered language to use
+ * Returns a ast_filestream pointer if it opens the file, NULL on error
+ */
+struct ast_filestream *ast_openvstream(struct ast_channel *chan, const char *filename, const char *preflang);
+
+/*! Applys a open stream to a channel. */
+/*!
+ * \param chan channel to work
+ * \param s ast_filestream to apply
+ * Returns 0 for success, -1 on failure
+ */
+int ast_applystream(struct ast_channel *chan, struct ast_filestream *s);
+
+/*! play a open stream on a channel. */
+/*!
+ * \param s filestream to play
+ * Returns 0 for success, -1 on failure
+ */
+int ast_playstream(struct ast_filestream *s);
+
+/*! 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
+ * Returns 0 for success, or -1 for error
+ */
+int ast_seekstream(struct ast_filestream *fs, off_t sample_offset, int whence);
+
+/*! Trunc stream at current location */
+/*!
+ * \param fs filestream to act on
+ * Returns 0 for success, or -1 for error
+ */
+int ast_truncstream(struct ast_filestream *fs);
+
+/*! Fast forward stream ms */
+/*!
+ * \param fs filestream to act on
+ * \param ms milliseconds to move
+ * Returns 0 for success, or -1 for error
+ */
+int ast_stream_fastforward(struct ast_filestream *fs, off_t ms);
+
+/*! Rewind stream ms */
+/*!
+ * \param fs filestream to act on
+ * \param ms milliseconds to move
+ * Returns 0 for success, or -1 for error
+ */
+int ast_stream_rewind(struct ast_filestream *fs, off_t ms);
+
+/*! Tell where we are in a stream */
+/*!
+ * \param fs fs to act on
+ * Returns a long as a sample offset into stream
+ */
+off_t ast_tellstream(struct ast_filestream *fs);
+
+/*! Read a frame from a filestream */
+/*!
+ * \param s ast_filestream to act on
+ * Returns a frame or NULL if read failed
+ */
+struct ast_frame *ast_readframe(struct ast_filestream *s);
+
+/*!\brief destroy a filestream using an ast_frame as input
+ *
+ * This is a hack that is used also by the ast_trans_pvt and
+ * ast_dsp structures. When a structure contains an ast_frame
+ * pointer as one of its fields. It may be that the frame is
+ * still used after the outer structure is freed. This leads to
+ * invalid memory accesses. This function allows for us to hold
+ * off on destroying the ast_filestream until we are done using
+ * the ast_frame pointer that is part of it
+ *
+ * \param fr The ast_frame that is part of an ast_filestream we wish
+ * to free.
+ */
+void ast_filestream_frame_freed(struct ast_frame *fr);
+
+/*! Initialize file stuff */
+/*!
+ * Initializes all the various file stuff. Basically just registers the cli stuff
+ * Returns 0 all the time
+ */
+int ast_file_init(void);
+
+
+#define AST_RESERVED_POINTERS 20
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _ASTERISK_FILE_H */
diff --git a/include/asterisk/frame.h b/include/asterisk/frame.h
new file mode 100644
index 000000000..6ee131eb2
--- /dev/null
+++ b/include/asterisk/frame.h
@@ -0,0 +1,597 @@
+/*
+ * 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/types.h>
+#include <sys/time.h>
+
+#include "asterisk/compiler.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
+ \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
+ \arg \b SRCUPDATE The source of media has changed
+
+*/
+
+/*!
+ * \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.
+ */
+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),
+ /*! This frame came from a dsp and is still the original frame.
+ * The dsp cannot be free'd if the frame inside of it still has
+ * this flag set. */
+ AST_FRFLAG_FROM_DSP = (1 << 2),
+ /*! This frame came from a filestream and is still the original frame.
+ * The filestream cannot be free'd if the frame inside of it still has
+ * this flag set. */
+ AST_FRFLAG_FROM_FILESTREAM = (1 << 3),
+};
+
+/*! \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)
+/*! Maximum audio format */
+#define AST_FORMAT_MAX_AUDIO (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)
+/*! Maximum video format */
+#define AST_FORMAT_MAX_VIDEO (1 << 24)
+#define AST_FORMAT_VIDEO_MASK (((1 << 25)-1) & ~(AST_FORMAT_AUDIO_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 */
+ AST_CONTROL_SRCUPDATE = 20, /*!< Indicate source of media has changed */
+};
+
+#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 visible; /*!< Can we see this entry */
+ int bits; /*!< bitmask value */
+ char *name; /*!< short name */
+ 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);
+
+struct ast_smoother;
+
+struct ast_format_list *ast_get_format_list_index(int index);
+struct ast_format_list *ast_get_format_list(size_t *size);
+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
+
+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" See \ref AudioCodecPref */
+void ast_codec_pref_init(struct ast_codec_pref *pref);
+
+/*! \brief Codec located at a particular place in the preference index See \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
+ */
+void 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);
+
+/*!
+ * \brief Get the sample rate for a given format.
+ */
+static force_inline int ast_format_rate(int format)
+{
+ if (format == AST_FORMAT_G722)
+ return 16000;
+
+ return 8000;
+}
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _ASTERISK_FRAME_H */
diff --git a/include/asterisk/fskmodem.h b/include/asterisk/fskmodem.h
new file mode 100644
index 000000000..e6d1a5419
--- /dev/null
+++ b/include/asterisk/fskmodem.h
@@ -0,0 +1,72 @@
+/*
+ * 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.
+ * \todo Translate Emiliano Zapata's spanish comments to english, please.
+ */
+
+#ifndef _ASTERISK_FSKMODEM_H
+#define _ASTERISK_FSKMODEM_H
+
+#define PARITY_NONE 0
+#define PARITY_EVEN 1
+#define PARITY_ODD 2
+
+
+#define NCOLA 0x4000
+
+typedef struct {
+ float spb; /*!< Samples / Bit */
+ int nbit; /*!< Number of Data Bits (5,7,8) */
+ float nstop; /*!< Number of Stop Bits 1,1.5,2 */
+ int paridad; /*!< Parity 0=none 1=even 2=odd */
+ int hdlc; /*!< Modo Packet */
+ float x0;
+ float x1;
+ float x2;
+ float cont;
+ int bw; /*!< Ancho de Banda */
+ double fmxv[8],fmyv[8]; /*!< filter stuff for M filter */
+ int fmp; /*!< pointer for M filter */
+ double fsxv[8],fsyv[8]; /*!< filter stuff for S filter */
+ int fsp; /*!< pointer for S filter */
+ double flxv[8],flyv[8]; /*!< filter stuff for L filter */
+ int flp; /*!< pointer for L filter */
+ int f_mark_idx; /*!< Indice de frecuencia de marca (f_M-500)/5 */
+ int f_space_idx; /*!< Indice de frecuencia de espacio (f_S-500)/5 */
+ int state;
+ int pcola; /*!< Puntero de las colas de datos */
+ float cola_in[NCOLA]; /*!< Cola de muestras de entrada */
+ float cola_filtro[NCOLA]; /*!< Cola de muestras tras filtros */
+ float cola_demod[NCOLA]; /*!< Cola de muestras demoduladas */
+} 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
+ He must be called with at least 80 bytes of buffer. */
+int fsk_serie(fsk_data *fskd, short *buffer, int *len, int *outbyte);
+
+#endif /* _ASTERISK_FSKMODEM_H */
diff --git a/include/asterisk/global_datastores.h b/include/asterisk/global_datastores.h
new file mode 100644
index 000000000..510034b0d
--- /dev/null
+++ b/include/asterisk/global_datastores.h
@@ -0,0 +1,47 @@
+/*
+ * 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"
+
+#define MAX_DIAL_FEATURE_OPTIONS 30
+
+extern const struct ast_datastore_info dialed_interface_info;
+
+extern const struct ast_datastore_info dial_features_info;
+
+struct ast_dialed_interface {
+ AST_LIST_ENTRY(ast_dialed_interface) list;
+ char interface[1];
+};
+
+struct ast_dial_features {
+ struct ast_flags features_caller;
+ struct ast_flags features_callee;
+ char options[MAX_DIAL_FEATURE_OPTIONS];
+ int is_caller;
+};
+
+#endif
diff --git a/include/asterisk/http.h b/include/asterisk/http.h
new file mode 100644
index 000000000..ba6f094e4
--- /dev/null
+++ b/include/asterisk/http.h
@@ -0,0 +1,65 @@
+/*
+ * 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"
+
+/*!
+ \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>
+*/
+
+/*! \brief HTTP Callbacks take the socket, 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.
+ 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) */
+typedef char *(*ast_http_callback)(struct sockaddr_in *requestor, const char *uri, struct ast_variable *params, int *status, char **title, int *contentlength);
+
+struct ast_http_uri {
+ struct ast_http_uri *next;
+ 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 a malloc()'d string containing an HTTP error message */
+char *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);
+
+char *ast_http_setcookie(const char *var, const char *val, int expires, char *buf, size_t buflen);
+
+int ast_http_init(void);
+int ast_http_reload(void);
+
+#endif /* _ASTERISK_SRV_H */
diff --git a/include/asterisk/image.h b/include/asterisk/image.h
new file mode 100644
index 000000000..72d1a4018
--- /dev/null
+++ b/include/asterisk/image.h
@@ -0,0 +1,96 @@
+/*
+ * 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 {
+ /*! Name */
+ char *name;
+ /*! Description */
+ char *desc;
+ /*! Extension(s) (separated by '|' ) */
+ char *exts;
+ /*! Image format */
+ int format;
+ /*! Read an image from a file descriptor */
+ struct ast_frame *(*read_image)(int fd, int len);
+ /*! Identify if this is that type of file */
+ int (*identify)(int fd);
+ /*! Returns length written */
+ int (*write_image)(int fd, struct ast_frame *frame);
+ /*! For linked list */
+ AST_LIST_ENTRY(ast_imager) list;
+};
+
+/*! Check for image support on a channel */
+/*!
+ * \param chan channel to check
+ * Checks the channel to see if it supports the transmission of images
+ * Returns non-zero if image transmission is supported
+ */
+int ast_supports_images(struct ast_channel *chan);
+
+/*! 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.
+ * Returns 0 on success, -1 on error
+ */
+int ast_send_image(struct ast_channel *chan, char *filename);
+
+/*! 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
+ * Returns an ast_frame on success, NULL on failure
+ */
+struct ast_frame *ast_read_image(char *filename, const char *preflang, int format);
+
+/*! Register image format */
+/*!
+ * \param imgdrv Populated ast_imager structure with info to register
+ * Registers an image format
+ * Returns 0 regardless
+ */
+int ast_image_register(struct ast_imager *imgdrv);
+
+/*! 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);
+
+/*! Initialize image stuff */
+/*!
+ * Initializes all the various image stuff. Basically just registers the cli stuff
+ * Returns 0 all the time
+ */
+int ast_image_init(void);
+
+#endif /* _ASTERISK_IMAGE_H */
diff --git a/include/asterisk/indications.h b/include/asterisk/indications.h
new file mode 100644
index 000000000..be0635c90
--- /dev/null
+++ b/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"
+
+struct tone_zone_sound {
+ struct tone_zone_sound *next; /* next element */
+ const char *name; /* Identifing name */
+ const char *data; /* Actual zone description */
+ /* 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 tone_zone {
+ struct tone_zone* next; /* next in 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 tone_zone_sound *tones; /* The known tones for this zone */
+};
+
+/* set the default tone country */
+int ast_set_indication_country(const char *country);
+
+/* locate ind_tone_zone, given the country. if country == NULL, use the default country */
+struct tone_zone *ast_get_indication_zone(const char *country);
+/* locate a tone_zone_sound, given the tone_zone. if tone_zone == NULL, use the default tone_zone */
+struct tone_zone_sound *ast_get_indication_tone(const struct tone_zone *zone, const char *indication);
+
+/* add a new country, if country exists, it will be replaced. */
+int ast_register_indication_country(struct tone_zone *country);
+/* remove an existing country and all its indications, country must exist */
+int ast_unregister_indication_country(const char *country);
+/* 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 tone_zone *zone, const char *indication, const char *tonelist);
+/* remove an existing tone_zone's indication. tone_zone must exist */
+int ast_unregister_indication(struct tone_zone *zone, const char *indication);
+
+/* Start a tone-list going */
+int ast_playtones_start(struct ast_channel *chan, int vol, const char* tonelist, int interruptible);
+/*! Stop the tones from playing */
+void ast_playtones_stop(struct ast_channel *chan);
+
+/* support for walking through a list of indications */
+struct tone_zone *ast_walk_indications(const struct tone_zone *cur);
+
+#if 0
+extern struct tone_zone *tone_zones;
+extern ast_mutex_t tzlock;
+#endif
+
+#endif /* _ASTERISK_INDICATIONS_H */
diff --git a/include/asterisk/inline_api.h b/include/asterisk/inline_api.h
new file mode 100644
index 000000000..2347d09d7
--- /dev/null
+++ b/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/include/asterisk/io.h b/include/asterisk/io.h
new file mode 100644
index 000000000..66ebceea0
--- /dev/null
+++ b/include/asterisk/io.h
@@ -0,0 +1,145 @@
+/*
+ * 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 POLLCOMPAT
+#include "asterisk/poll-compat.h"
+#else
+#include <sys/poll.h> /* For POLL* constants */
+#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
+
+/*
+ * 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;
+
+/*! Creates a context */
+/*!
+ * Create a context for I/O operations
+ * Basically mallocs an IO structure and sets up some default values.
+ * Returns an allocated io_context structure
+ */
+struct io_context *io_context_create(void);
+
+/*! 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))
+
+/*! 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. Returns a pointer to ID of the IO event, or NULL on failure.
+ */
+int *ast_io_add(struct io_context *ioc, int fd, ast_io_cb callback, short events, void *data);
+
+/*! 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. Returns a pointero to the ID of the IO event,
+ * or NULL on failure.
+ */
+int *ast_io_change(struct io_context *ioc, int *id, int fd, ast_io_cb callback, short events, void *data);
+
+/*! 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 Returns 0 on success or -1 on failure.
+ */
+int ast_io_remove(struct io_context *ioc, int *id);
+
+/*! 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. Returns the number of
+ * I/O events which took place.
+ */
+int ast_io_wait(struct io_context *ioc, int howlong);
+
+/*! 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);
+
+/*! 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/include/asterisk/jabber.h b/include/asterisk/jabber.h
new file mode 100644
index 000000000..39618cd4b
--- /dev/null
+++ b/include/asterisk/jabber.h
@@ -0,0 +1,146 @@
+/*
+ * 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.
+ */
+
+#ifndef _ASTERISK_JABBER_H
+#define _ASTERISK_JABBER_H
+
+#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);
+ struct aji_resource *resources;
+ 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 sid[10]; /* Session ID */
+ char mid[6]; /* Message ID */
+ iksid *jid;
+ iksparser *p;
+ iksfilter *f;
+ ikstack *stack;
+ 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;
+};
+
+struct aji_client_container{
+ ASTOBJ_CONTAINER_COMPONENTS(struct aji_client);
+};
+
+int ast_aji_send(struct aji_client *client, const char *address, const char *message);
+int ast_aji_disconnect(struct aji_client *client);
+int ast_aji_check_roster(void);
+void ast_aji_increment_mid(char *mid);
+int ast_aji_create_chat(struct aji_client *client,char *room, char *server, char *topic);
+int ast_aji_invite_chat(struct aji_client *client, char *user, char *room, char *message);
+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/include/asterisk/jingle.h b/include/asterisk/jingle.h
new file mode 100644
index 000000000..0968b7394
--- /dev/null
+++ b/include/asterisk/jingle.h
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+#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://jabber.org/protocol/jingle"
+#define GOOGLE_NS "http://www.google.com/session"
+
+#define JINGLE_SID "sid"
+#define GOOGLE_SID "id"
+
+#define JINGLE_INITIATE "initiate"
+
+#define JINGLE_ACCEPT "accept"
+#define GOOGLE_ACCEPT "accept"
+
+#define JINGLE_NEGOTIATE "negotiate"
+#define GOOGLE_NEGOTIATE "candidates"
+
+#endif
diff --git a/include/asterisk/linkedlists.h b/include/asterisk/linkedlists.h
new file mode 100644
index 000000000..e7511fd8a
--- /dev/null
+++ b/include/asterisk/linkedlists.h
@@ -0,0 +1,761 @@
+/*
+ * 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.
+ Returns 0 on success, 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.
+ Returns 0 on success, 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.
+ Returns 0 on success, 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.
+ Returns 0 on success, 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.
+ Returns 0 on success, 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.
+ Returns 0 on success, 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
+
+ Returns non-zero if the list has entries, 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)->first) __list_next; \
+ typeof((head)->first) __list_prev = NULL; \
+ typeof((head)->first) __new_prev = NULL; \
+ for ((var) = (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 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.
+
+ \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(head, field) do { \
+ __new_prev->field.next = NULL; \
+ __new_prev = __list_prev; \
+ if (__list_prev) \
+ __list_prev->field.next = __list_next; \
+ else \
+ (head)->first = __list_next; \
+ if (!__list_next) \
+ (head)->last = __list_prev; \
+ } while (0)
+
+#define AST_RWLIST_REMOVE_CURRENT AST_LIST_REMOVE_CURRENT
+
+/*!
+ \brief Inserts a list entry before the current entry during a traversal.
+ \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.
+
+ \note This macro can \b only be used inside an AST_LIST_TRAVERSE_SAFE_BEGIN()
+ block.
+ */
+#define AST_LIST_INSERT_BEFORE_CURRENT(head, elm, field) do { \
+ if (__list_prev) { \
+ (elm)->field.next = __list_prev->field.next; \
+ __list_prev->field.next = elm; \
+ } else { \
+ (elm)->field.next = (head)->first; \
+ (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/include/asterisk/localtime.h b/include/asterisk/localtime.h
new file mode 100644
index 000000000..313a8ddb6
--- /dev/null
+++ b/include/asterisk/localtime.h
@@ -0,0 +1,30 @@
+/*
+ * 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 tm *ast_localtime(const time_t *timep, struct tm *p_tm, const char *zone);
+time_t ast_mktime(struct tm * const tmp, const char *zone);
+
+#endif /* _ASTERISK_LOCALTIME_H */
diff --git a/include/asterisk/lock.h b/include/asterisk/lock.h
new file mode 100644
index 000000000..bcf802451
--- /dev/null
+++ b/include/asterisk/lock.h
@@ -0,0 +1,1253 @@
+/*
+ * 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 locking definitions.
+ *
+ * - 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 <netdb.h>
+#include <time.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(PTHREAD_RECURSIVE_MUTEX_INITIALIZER_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 */
+
+#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>
+#include <string.h>
+#include <stdio.h>
+#include <unistd.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_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.
+ */
+#if !defined(LOW_MEMORY)
+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);
+#else
+#define ast_store_lock_info(I,DONT,CARE,ABOUT,THE,PARAMETERS)
+#endif
+
+
+/*!
+ * \brief Mark the last lock as acquired
+ */
+#if !defined(LOW_MEMORY)
+void ast_mark_lock_acquired(void *lock_addr);
+#else
+#define ast_mark_lock_acquired(ignore)
+#endif
+
+/*!
+ * \brief Mark the last lock as failed (trylock)
+ */
+#if !defined(LOW_MEMORY)
+void ast_mark_lock_failed(void *lock_addr);
+#else
+#define ast_mark_lock_failed(ignore)
+#endif
+
+/*!
+ * \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.
+ */
+#if !defined(LOW_MEMORY)
+void ast_remove_lock_info(void *lock_addr);
+#else
+#define ast_remove_lock_info(ignore)
+#endif
+
+/*!
+ * \brief retrieve lock info for the specified mutex
+ *
+ * this gets called during deadlock avoidance, so that the information may
+ * be preserved as to what location originally acquired the lock.
+ */
+#if !defined(LOW_MEMORY)
+int ast_find_lock_info(void *lock_addr, char *filename, size_t filename_size, int *lineno, char *func, size_t func_size, char *mutex_name, size_t mutex_name_size);
+#else
+#define ast_find_lock_info(a,b,c,d,e,f,g,h) -1
+#endif
+
+/*!
+ * \brief Unlock a lock briefly
+ *
+ * used during deadlock avoidance, to preserve the original location where
+ * a lock was originally acquired.
+ */
+#define DEADLOCK_AVOIDANCE(lock) \
+ do { \
+ char __filename[80], __func[80], __mutex_name[80]; \
+ int __lineno; \
+ int __res = ast_find_lock_info(lock, __filename, sizeof(__filename), &__lineno, __func, sizeof(__func), __mutex_name, sizeof(__mutex_name)); \
+ ast_mutex_unlock(lock); \
+ usleep(1); \
+ if (__res < 0) { /* Shouldn't ever happen, but just in case... */ \
+ ast_mutex_lock(lock); \
+ } else { \
+ __ast_pthread_mutex_lock(__filename, __lineno, __func, __mutex_name, lock); \
+ } \
+ } while (0)
+
+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(&t->mutex);
+ } 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(&t->mutex);
+ } else if (t->track) {
+ ast_mark_lock_failed(&t->mutex);
+ }
+
+ 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 */
+
+#define DEADLOCK_AVOIDANCE(lock) \
+ ast_mutex_unlock(lock); \
+ usleep(1); \
+ ast_mutex_lock(lock);
+
+
+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
+ destructors to destroy mutexes and create it on the fly. */
+#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 */
+
+#define pthread_mutex_t use_ast_mutex_t_instead_of_pthread_mutex_t
+#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_t use_ast_cond_t_instead_of_pthread_cond_t
+#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
+
+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 NULL
+#endif
+
+#ifdef DEBUG_THREADS
+
+#define ast_rwlock_init(rwlock) __ast_rwlock_init(__FILE__, __LINE__, __PRETTY_FUNCTION__, #rwlock, rwlock)
+
+
+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;
+}
+
+#define ast_rwlock_destroy(rwlock) __ast_rwlock_destroy(__FILE__, __LINE__, __PRETTY_FUNCTION__, #rwlock, rwlock)
+
+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;
+}
+
+#define ast_rwlock_unlock(a) \
+ _ast_rwlock_unlock(a, # a, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+
+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;
+}
+
+#define ast_rwlock_rdlock(a) \
+ _ast_rwlock_rdlock(a, # a, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+
+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(lock);
+ else
+ ast_remove_lock_info(lock);
+ return res;
+}
+
+#define ast_rwlock_wrlock(a) \
+ _ast_rwlock_wrlock(a, # a, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+
+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(lock);
+ else
+ ast_remove_lock_info(lock);
+ return res;
+}
+
+#define ast_rwlock_tryrdlock(a) \
+ _ast_rwlock_tryrdlock(a, # a, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+
+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(lock);
+ else
+ ast_remove_lock_info(lock);
+ return res;
+}
+
+#define ast_rwlock_trywrlock(a) \
+ _ast_rwlock_trywrlock(a, # a, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+
+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(lock);
+ 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)
+
+/*
+ * Initial 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__)
+#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)
+/*! \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)
+/*! \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)
+#else
+
+struct ast_channel;
+
+#define ast_channel_lock(a) __ast_channel_lock(a, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+/*! \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, const char *file, int lineno, const char *func);
+
+#define ast_channel_unlock(a) __ast_channel_unlock(a, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+/*! \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, const char *file, int lineno, const char *func);
+
+#define ast_channel_trylock(a) __ast_channel_trylock(a, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+/*! \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, const char *file, int lineno, const char *func);
+#endif
+
+#endif /* _ASTERISK_LOCK_H */
diff --git a/include/asterisk/logger.h b/include/asterisk/logger.h
new file mode 100644
index 000000000..af0bb3c01
--- /dev/null
+++ b/include/asterisk/logger.h
@@ -0,0 +1,139 @@
+/*
+ * 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/compat.h"
+
+#include <stdarg.h>
+
+#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 " > "
+
+/*! Used for sending a log message */
+/*!
+ \brief 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_
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _ASTERISK_LOGGER_H */
diff --git a/include/asterisk/manager.h b/include/asterisk/manager.h
new file mode 100644
index 000000000..34ae43235
--- /dev/null
+++ b/include/asterisk/manager.h
@@ -0,0 +1,148 @@
+/*
+ * 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 <stdarg.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.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.
+
+ 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)
+
+ ** Please try to re-use existing 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
+ */
+
+#define DEFAULT_MANAGER_PORT 5038 /* Default port for Asterisk management via TCP */
+
+#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 */
+
+/* Export manager structures */
+#define AST_MAX_MANHEADERS 128
+
+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 */
+ struct manager_action *next;
+};
+
+/* External routines may register/unregister manager callbacks this way */
+#define ast_manager_register(a, b, c, d) ast_manager_register2(a, b, c, d, NULL)
+
+/* Use ast_manager_register2 to register with help text for new manager commands */
+
+/*! 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);
+
+/*! 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
+ * \returns 1 if the session has the permission mask capabilities, otherwise 0
+ */
+int astman_verify_session_readpermissions(uint32_t ident, int perm);
+
+/*!
+ * \brief Verify a session's write permissions against a permission mask.
+ * \param ident session identity
+ * \param perm permission mask to verify
+ * \returns 1 if the session has the permission mask capabilities, otherwise 0
+ */
+int astman_verify_session_writepermissions(uint32_t ident, int perm);
+
+/*! 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
+*/
+int __attribute__((format(printf, 3,4))) manager_event(int category, const char *event, const char *contents, ...);
+
+/*! Get header from mananger transaction */
+const char *astman_get_header(const struct message *m, char *var);
+
+/*! Get a linked list of the Variable: headers */
+struct ast_variable *astman_get_variables(const struct message *m);
+
+/*! Send error in manager transaction */
+void astman_send_error(struct mansession *s, const struct message *m, char *error);
+void astman_send_response(struct mansession *s, const struct message *m, char *resp, char *msg);
+void astman_send_ack(struct mansession *s, const struct message *m, char *msg);
+
+void __attribute__((format(printf, 2, 3))) astman_append(struct mansession *s, const char *fmt, ...);
+
+/*! Called by Asterisk initialization */
+int init_manager(void);
+int reload_manager(void);
+
+#endif /* _ASTERISK_MANAGER_H */
diff --git a/include/asterisk/md5.h b/include/asterisk/md5.h
new file mode 100644
index 000000000..f738bd5b6
--- /dev/null
+++ b/include/asterisk/md5.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
+ * \brief MD5 digest functions
+ */
+
+#ifndef _ASTERISK_MD5_H
+#define _ASTERISK_MD5_H
+
+#include <inttypes.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/include/asterisk/module.h b/include/asterisk/module.h
new file mode 100644
index 000000000..27eae4abe
--- /dev/null
+++ b/include/asterisk/module.h
@@ -0,0 +1,292 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2006, 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).
+ *
+ * \return Zero on success, -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 LOCAL_USER macros 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 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.
+ *
+ * \return Zero on success and -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.
+ *
+ * \return Zero on success, -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.
+ *
+ * \return A possible completion of the partial match, or 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...)
+ * whose functions are exported through fields of a "struct module_symbol";
+ */
+
+enum ast_module_flags {
+ AST_MODFLAG_DEFAULT = 0,
+ AST_MODFLAG_GLOBAL_SYMBOLS = (1 << 0),
+ AST_MODFLAG_BUILDSUM = (1 << 1),
+};
+
+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 */
+ 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, \
+ desc, \
+ keystr, \
+ flags_to_set | AST_MODFLAG_BUILDSUM, \
+ 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
+/* 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;
+
+#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...) \
+ static struct ast_module_info __mod_info = { \
+ .name = AST_MODULE, \
+ .flags = flags_to_set | AST_MODFLAG_BUILDSUM, \
+ .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
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _ASTERISK_MODULE_H */
diff --git a/include/asterisk/monitor.h b/include/asterisk/monitor.h
new file mode 100644
index 000000000..935a33240
--- /dev/null
+++ b/include/asterisk/monitor.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 Channel monitoring
+ */
+
+#ifndef _ASTERISK_MONITOR_H
+#define _ASTERISK_MONITOR_H
+
+#include "asterisk/channel.h"
+
+enum AST_MONITORING_STATE {
+ AST_MONITOR_RUNNING,
+ AST_MONITOR_PAUSED
+};
+
+/*! 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 );
+
+/* 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/include/asterisk/musiconhold.h b/include/asterisk/musiconhold.h
new file mode 100644
index 000000000..8a8018d19
--- /dev/null
+++ b/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 0 success
+ * \retval non-zero 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/include/asterisk/netsock.h b/include/asterisk/netsock.h
new file mode 100644
index 000000000..73a2dd224
--- /dev/null
+++ b/include/asterisk/netsock.h
@@ -0,0 +1,68 @@
+/*
+ * 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 <netinet/in.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, 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, 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_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/include/asterisk/options.h b/include/asterisk/options.h
new file mode 100644
index 000000000..01eab6e29
--- /dev/null
+++ b/include/asterisk/options.h
@@ -0,0 +1,138 @@
+/*
+ * 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
+#define AST_CHANNEL_NAME 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),
+ /*! Enable priority jumping in applications */
+ AST_OPT_FLAG_PRIORITY_JUMPING = (1 << 11),
+ /*! 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() and DTMF Generation */
+ 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)
+};
+
+/*! 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_priority_jumping ast_test_flag(&ast_options, AST_OPT_FLAG_PRIORITY_JUMPING)
+#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)
+
+extern struct ast_flags ast_options;
+
+extern int option_verbose;
+extern int option_debug; /*!< Debugging */
+extern int option_maxcalls; /*!< Maximum number of simultaneous channels */
+extern double option_maxload;
+extern char defaultlanguage[];
+
+extern time_t ast_startuptime;
+extern time_t ast_lastreloadtime;
+extern pid_t ast_mainpid;
+
+extern char record_cache_dir[AST_CACHE_DIR_LEN];
+extern char debug_filename[AST_FILENAME_MAX];
+extern const char *dahdi_chan_name;
+extern const size_t *dahdi_chan_name_len;
+extern const enum dahdi_chan_modes {
+ CHAN_ZAP_MODE,
+ CHAN_DAHDI_PLUS_ZAP_MODE,
+} *dahdi_chan_mode;
+
+extern int ast_language_is_prefix;
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _ASTERISK_OPTIONS_H */
diff --git a/include/asterisk/paths.h b/include/asterisk/paths.h
new file mode 100644
index 000000000..d90dd9544
--- /dev/null
+++ b/include/asterisk/paths.h
@@ -0,0 +1,43 @@
+/*
+ * 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
+
+#include <limits.h>
+
+extern char ast_config_AST_CONFIG_DIR[PATH_MAX];
+extern char ast_config_AST_CONFIG_FILE[PATH_MAX];
+extern char ast_config_AST_MODULE_DIR[PATH_MAX];
+extern char ast_config_AST_SPOOL_DIR[PATH_MAX];
+extern char ast_config_AST_MONITOR_DIR[PATH_MAX];
+extern char ast_config_AST_VAR_DIR[PATH_MAX];
+extern char ast_config_AST_DATA_DIR[PATH_MAX];
+extern char ast_config_AST_LOG_DIR[PATH_MAX];
+extern char ast_config_AST_AGI_DIR[PATH_MAX];
+extern char ast_config_AST_DB[PATH_MAX];
+extern char ast_config_AST_KEY_DIR[PATH_MAX];
+extern char ast_config_AST_PID[PATH_MAX];
+extern char ast_config_AST_SOCKET[PATH_MAX];
+extern char ast_config_AST_RUN_DIR[PATH_MAX];
+extern char ast_config_AST_CTL_PERMISSIONS[PATH_MAX];
+extern char ast_config_AST_CTL_OWNER[PATH_MAX];
+extern char ast_config_AST_CTL_GROUP[PATH_MAX];
+extern char ast_config_AST_CTL[PATH_MAX];
+extern char ast_config_AST_SYSTEM_NAME[20];
+
+#endif /* _ASTERISK_PATHS_H */
diff --git a/include/asterisk/pbx.h b/include/asterisk/pbx.h
new file mode 100644
index 000000000..0ac09f39d
--- /dev/null
+++ b/include/asterisk/pbx.h
@@ -0,0 +1,915 @@
+/*
+ * 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/channel.h"
+#include "asterisk/linkedlists.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_KEEPALIVE 10 /*!< Destroy the thread, but don't hang up the channel */
+/*! } */
+
+#define PRIORITY_HINT -1 /*!< Special Priority for a hint */
+
+/*! \brief Extension states */
+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 *, char *, char *, char *, size_t); /*!< Read function, if read is supported */
+ int (*write)(struct ast_channel *, char *, char *, const char *); /*!< Write function, if write is supported */
+ AST_LIST_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 appliation 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);
+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);
+
+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.
+ *
+ * \return Zero on success, 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.
+ *
+ * \return Zero on success, 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 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.
+ */
+int ast_register_application(const char *app, int (*execute)(struct ast_channel *, void *),
+ const char *synopsis, const char *description);
+
+/*!
+ * \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);
+
+/*!
+ * \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 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
+ *
+ * \note It is possible for autoservice to be started and stopped on c during this
+ * function call, it is important that c is not locked prior to calling this. Otherwise
+ * a deadlock may occur
+ *
+ * \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
+ *
+ * \note It is possible for autoservice to be started and stopped on c during this
+ * function call, it is important that c is not locked prior to calling this. Otherwise
+ * a deadlock may occur
+ *
+ * \return the priority which matches the given label in the extension or -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 It is possible for autoservice to be started and stopped on c during this
+ * function call, it is important that c is not locked prior to calling this. Otherwise
+ * a deadlock may occur
+ *
+ * \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
+ *
+ * \note It is possible for autoservice to be started and stopped on c during this
+ * function call, it is important that c is not locked prior to calling this. Otherwise
+ * a deadlock may occur
+ *
+ * \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
+ *
+ * \note It is possible for autoservice to be started and stopped on c during this
+ * function call, it is important that c is not locked prior to calling this. Otherwise
+ * a deadlock may occur
+ *
+ * \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 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
+ *
+ * This adds a new extension to the asterisk extension list.
+ *
+ * \note It is possible for autoservice to be started and stopped on c during this
+ * function call, it is important that c is not locked prior to calling this. Otherwise
+ * a deadlock may occur
+ *
+ * \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);
+
+/*!
+ * \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 (0 to remove all)
+ * \param callerid NULL to remove all; non-NULL to match a single record per priority
+ * \param matchcid non-zero to match callerid element (if non-NULL); 0 to match default case
+ * \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);
+
+int ast_context_remove_extension_callerid(const char *context, const char *extension,
+ int priority, const char *callerid, int matchcid, const char *registrar);
+
+int ast_context_remove_extension_callerid2(struct ast_context *con, const char *extension,
+ int priority, const char *callerid, int matchcid, 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 Locks the context list
+ *
+ * \retval 0 on success
+ * \retval -1 on error
+ */
+int ast_lock_contexts(void); /* equivalent to wrlock */
+int ast_rdlock_contexts(void);
+int ast_wrlock_contexts(void);
+
+/*!
+ * \brief Unlocks contexts
+ *
+ * \retval 0 on success
+ * \retval -1 on failure
+ */
+int ast_unlock_contexts(void);
+
+/*!
+ * \brief Locks a given context
+ *
+ * \param con context to lock
+ *
+ * \retval 0 on success
+ * \retval -1 on failure
+ */
+int ast_lock_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);
+
+/* 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);
+
+/* 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);
+
+/* 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, char *buf, size_t size);
+
+/*!
+ * \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);
+
+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);
+
+/*!
+ * \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 Reigster a custom function
+ */
+int ast_custom_function_register(struct ast_custom_function *acf);
+
+/*!
+ * \brief Retrieve the number of active calls
+ */
+int ast_active_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, 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, char *function, const char *value);
+
+void ast_hint_state_changed(const char *device);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _ASTERISK_PBX_H */
diff --git a/include/asterisk/plc.h b/include/asterisk/plc.h
new file mode 100644
index 000000000..762504952
--- /dev/null
+++ b/include/asterisk/plc.h
@@ -0,0 +1,161 @@
+/*! \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_
+
+#ifdef SOLARIS
+#include <sys/int_types.h>
+#else
+#if defined(__OpenBSD__) || defined( __FreeBSD__)
+#include <inttypes.h>
+#else
+#include <stdint.h>
+#endif
+#endif
+
+/*! \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/include/asterisk/poll-compat.h b/include/asterisk/poll-compat.h
new file mode 100644
index 000000000..5f795a894
--- /dev/null
+++ b/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/include/asterisk/privacy.h b/include/asterisk/privacy.h
new file mode 100644
index 000000000..686a14d75
--- /dev/null
+++ b/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/include/asterisk/res_odbc.h b/include/asterisk/res_odbc.h
new file mode 100644
index 000000000..4fbe007c4
--- /dev/null
+++ b/include/asterisk/res_odbc.h
@@ -0,0 +1,103 @@
+/*
+ * 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;
+
+struct odbc_obj {
+ ast_mutex_t lock;
+ SQLHDBC con; /* ODBC Connection Handle */
+ struct odbc_class *parent; /* Information about the connection is protected */
+ struct timeval last_used;
+ 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
+ * \return Returns 0 on success or -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) __attribute__((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.
+ * \return Returns an ODBC object or 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
+ * \return Returns 0 if connected, -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 backslash is a native escape character, 0 if an ESCAPE clause is needed to support '\'
+ */
+int ast_odbc_backslash_is_escape(struct odbc_obj *obj);
+
+/*! \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.
+ * \return Returns a statement handle or 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/include/asterisk/rtp.h b/include/asterisk/rtp.h
new file mode 100644
index 000000000..870529e5d
--- /dev/null
+++ b/include/asterisk/rtp.h
@@ -0,0 +1,265 @@
+/*
+ * 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 <netinet/in.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
+
+#define MAX_RTP_PT 256
+
+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;
+
+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);
+ /*! Set RTP peer */
+ int (* const set_rtp_peer)(struct ast_channel *chan, struct ast_rtp *peer, struct ast_rtp *vpeer, int codecs, int nat_active);
+ int (* const get_codec)(struct ast_channel *chan);
+ const char * const type;
+ AST_LIST_ENTRY(ast_rtp_protocol) list;
+};
+
+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 */
+};
+
+
+#define FLAG_3389_WARNING (1 << 0)
+
+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);
+
+void ast_rtp_destroy(struct ast_rtp *rtp);
+
+void ast_rtp_reset(struct ast_rtp *rtp);
+
+void ast_rtp_stun_request(struct ast_rtp *rtp, struct sockaddr_in *suggestion, const char *username);
+
+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_settos(struct ast_rtp *rtp, int tos);
+
+void ast_rtp_new_source(struct ast_rtp *rtp);
+
+/*! \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);
+
+int ast_rtp_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms);
+
+int ast_rtp_proto_register(struct ast_rtp_protocol *proto);
+
+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 *dest, struct ast_channel *src);
+
+void ast_rtp_stop(struct ast_rtp *rtp);
+
+/*! \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_new_init(struct ast_rtp *rtp);
+
+void ast_rtp_init(void);
+
+int ast_rtp_reload(void);
+
+int ast_rtp_codec_setpref(struct ast_rtp *rtp, struct ast_codec_pref *prefs);
+
+struct ast_codec_pref *ast_rtp_codec_getpref(struct ast_rtp *rtp);
+
+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/include/asterisk/say.h b/include/asterisk/say.h
new file mode 100644
index 000000000..17070c2c4
--- /dev/null
+++ b/include/asterisk/say.h
@@ -0,0 +1,158 @@
+/*
+ * 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
+
+/* 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
+ * Returns 0 on success, DTMF digit on interrupt, -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);
+
+/* 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
+ * Returns 0 on success, DTMF digit on interrupt, -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);
+
+/* 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
+ * Returns 0 on success, dtmf if interrupted, -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);
+
+/* 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
+ * Returns 0 on success, dtmf if interrupted, -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/include/asterisk/sched.h b/include/asterisk/sched.h
new file mode 100644
index 000000000..5a3124cb7
--- /dev/null
+++ b/include/asterisk/sched.h
@@ -0,0 +1,198 @@
+/*
+ * 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
+
+/*! \brief a loop construct to ensure that
+ * the scheduled task get deleted. The idea is that
+ * if we loop attempting to remove the scheduled task,
+ * then whatever callback had been running will complete
+ * and reinsert the task into the scheduler.
+ *
+ * Since macro expansion essentially works like pass-by-name
+ * parameter passing, this macro will still work correctly even
+ * if the id of the task to delete changes. This holds as long as
+ * the name of the id which could change is passed to the macro
+ * and not a copy of the value of the id.
+ */
+#define AST_SCHED_DEL(sched, id) \
+ ({ \
+ int _count = 0; \
+ int _sched_res = -1; \
+ while (id > -1 && (_sched_res = ast_sched_del(sched, id)) && ++_count < 10) \
+ usleep(1); \
+ if (_count == 10 && option_debug > 2) { \
+ ast_log(LOG_DEBUG, "Unable to cancel schedule ID %d.\n", id); \
+ } \
+ id = -1; \
+ (_sched_res); \
+ })
+
+#define AST_SCHED_DEL_SPINLOCK(sched, id, lock) \
+ ({ \
+ int _count = 0; \
+ int _sched_res = -1; \
+ while (id > -1 && (_sched_res = ast_sched_del(sched, id)) && ++_count < 10) { \
+ ast_mutex_unlock(lock); \
+ usleep(1); \
+ ast_mutex_lock(lock); \
+ } \
+ if (_count == 10 && option_debug > 2) { \
+ ast_log(LOG_DEBUG, "Unable to cancel schedule ID %d.\n", id); \
+ } \
+ id = -1; \
+ (_sched_res); \
+ })
+
+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);
+
+/*!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 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
+ */
+#ifndef AST_DEVMODE
+int ast_sched_del(struct sched_context *con, int id);
+#else
+int _ast_sched_del(struct sched_context *con, int id, const char *file, int line, const char *function);
+#define ast_sched_del(a, b) _ast_sched_del(a, b, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+#endif
+
+/*! \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/include/asterisk/sha1.h b/include/asterisk/sha1.h
new file mode 100644
index 000000000..fa8e2155b
--- /dev/null
+++ b/include/asterisk/sha1.h
@@ -0,0 +1,81 @@
+/*
+ * 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_
+
+
+
+#if defined(__OpenBSD__) || defined( __FreeBSD__)
+#include <inttypes.h>
+#else
+#include <stdint.h>
+#endif
+
+/*
+ * 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
+
+/*
+ * 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/include/asterisk/slinfactory.h b/include/asterisk/slinfactory.h
new file mode 100644
index 000000000..939384efd
--- /dev/null
+++ b/include/asterisk/slinfactory.h
@@ -0,0 +1,57 @@
+/*
+ * 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
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+#define AST_SLINFACTORY_MAX_HOLD 1280
+
+struct ast_slinfactory {
+ AST_LIST_HEAD_NOLOCK(, ast_frame) queue;
+ struct ast_trans_pvt *trans;
+ short hold[AST_SLINFACTORY_MAX_HOLD];
+ short *offset;
+ size_t holdlen; /*!< in samples */
+ unsigned int size; /*!< in samples */
+ unsigned int format;
+};
+
+void ast_slinfactory_init(struct ast_slinfactory *sf);
+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/include/asterisk/smdi.h b/include/asterisk/smdi.h
new file mode 100644
index 000000000..6c79b2bc8
--- /dev/null
+++ b/include/asterisk/smdi.h
@@ -0,0 +1,195 @@
+/*
+ * Asterisk -- A telephony toolkit for Linux.
+ *
+ * Copyright (C) 2005-2008, Digium, Inc.
+ *
+ * Matthew A. Nicholson <mnicholson@digium.com>
+ * 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 SMDI support for Asterisk.
+ * \author Matthew A. Nicholson <mnicholson@digium.com>
+ * \author Russell Bryant <russell@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 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 recieved on the interface.
+ */
+struct ast_smdi_interface;
+
+void ast_smdi_interface_unref(struct ast_smdi_interface *iface);
+
+/*!
+ * \brief Get the next SMDI message from the queue.
+ * \param iface a pointer to the interface to use.
+ *
+ * This function pulls the first unexpired message from the SMDI message queue
+ * on the specified interface. It will purge all expired SMDI messages before
+ * returning.
+ *
+ * \return the next SMDI message, or NULL if there were no pending messages.
+ */
+struct ast_smdi_md_message *ast_smdi_md_message_pop(struct ast_smdi_interface *iface);
+
+/*!
+ * \brief Get the next SMDI message from the queue.
+ * \param iface a pointer to the interface to use.
+ * \param timeout the time to wait before returning in milliseconds.
+ *
+ * This function pulls a message from the SMDI message queue on the specified
+ * interface. If no message is available this function will wait the specified
+ * amount of time before returning.
+ *
+ * \return the next SMDI message, or NULL if there were no pending messages and
+ * the timeout has expired.
+ */
+struct ast_smdi_md_message *ast_smdi_md_message_wait(struct ast_smdi_interface *iface, int timeout);
+
+/*!
+ * \brief Put an SMDI message back in the front of the queue.
+ * \param iface a pointer to the interface to use.
+ * \param md_msg a pointer to the message to use.
+ *
+ * This function puts a message back in the front of the specified queue. It
+ * should be used if a message was popped but is not going to be processed for
+ * some reason, and the message needs to be returned to the queue.
+ */
+void ast_smdi_md_message_putback(struct ast_smdi_interface *iface, struct ast_smdi_md_message *msg);
+
+/*!
+ * \brief Get the next SMDI message from the queue.
+ * \param iface a pointer to the interface to use.
+ *
+ * This function pulls the first unexpired message from the SMDI message queue
+ * on the specified interface. It will purge all expired SMDI messages before
+ * returning.
+ *
+ * \return the next SMDI message, or NULL if there were no pending messages.
+ */
+struct ast_smdi_mwi_message *ast_smdi_mwi_message_pop(struct ast_smdi_interface *iface);
+
+/*!
+ * \brief Get the next SMDI message from the queue.
+ * \param iface a pointer to the interface to use.
+ * \param timeout the time to wait before returning in milliseconds.
+ *
+ * This function pulls a message from the SMDI message queue on the specified
+ * interface. If no message is available this function will wait the specified
+ * amount of time before returning.
+ *
+ * \return the next SMDI message, or NULL if there were no pending messages and
+ * the timeout has expired.
+ */
+struct ast_smdi_mwi_message *ast_smdi_mwi_message_wait(struct ast_smdi_interface *iface, int timeout);
+struct ast_smdi_mwi_message *ast_smdi_mwi_message_wait_station(struct ast_smdi_interface *iface,
+ int timeout, const char *station);
+
+/*!
+ * \brief Put an SMDI message back in the front of the queue.
+ * \param iface a pointer to the interface to use.
+ * \param mwi_msg a pointer to the message to use.
+ *
+ * This function puts a message back in the front of the specified queue. It
+ * should be used if a message was popped but is not going to be processed for
+ * some reason, and the message needs to be returned to the queue.
+ */
+void ast_smdi_mwi_message_putback(struct ast_smdi_interface *iface, struct ast_smdi_mwi_message *msg);
+
+/*!
+ * \brief Find an SMDI interface with the specified name.
+ * \param iface_name the name/port of the interface to search for.
+ *
+ * \return a pointer to the interface located or NULL if none was found. This
+ * actually returns an ASTOBJ reference and should be released using
+ * #ASTOBJ_UNREF(iface, ast_smdi_interface_destroy).
+ */
+struct ast_smdi_interface *ast_smdi_interface_find(const char *iface_name);
+
+/*!
+ * \brief Set the MWI indicator for a mailbox.
+ * \param iface the interface to use.
+ * \param mailbox the mailbox to use.
+ */
+int ast_smdi_mwi_set(struct ast_smdi_interface *iface, const char *mailbox);
+
+/*!
+ * \brief Unset the MWI indicator for a mailbox.
+ * \param iface the interface to use.
+ * \param mailbox the mailbox to use.
+ */
+int ast_smdi_mwi_unset(struct ast_smdi_interface *iface, const char *mailbox);
+
+/*! \brief ast_smdi_md_message destructor. */
+void ast_smdi_md_message_destroy(struct ast_smdi_md_message *msg);
+
+/*! \brief ast_smdi_mwi_message destructor. */
+void ast_smdi_mwi_message_destroy(struct ast_smdi_mwi_message *msg);
+
+#endif /* !ASTERISK_SMDI_H */
diff --git a/include/asterisk/speech.h b/include/asterisk/speech.h
new file mode 100644
index 000000000..6e6432342
--- /dev/null
+++ b/include/asterisk/speech.h
@@ -0,0 +1,152 @@
+/*
+ * 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 */
+#define AST_SPEECH_QUIET (1 << 0) /* Quiet down output... they are talking */
+#define AST_SPEECH_SPOKE (1 << 1) /* Speaker did not speak */
+#define AST_SPEECH_HAVE_RESULTS (1 << 2) /* Results are present */
+
+/* Speech structure states - in order of expected change */
+#define AST_SPEECH_STATE_NOT_READY 0 /* Not ready to accept audio */
+#define AST_SPEECH_STATE_READY 1 /* Accepting audio */
+#define AST_SPEECH_STATE_WAIT 2 /* Wait for results to become available */
+#define AST_SPEECH_STATE_DONE 3 /* Processing is 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);
+ /*! 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 */
+ struct ast_speech_result *next;
+};
+
+/*! \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 format);
+/*! \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/include/asterisk/srv.h b/include/asterisk/srv.h
new file mode 100644
index 000000000..567b40844
--- /dev/null
+++ b/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/include/asterisk/stringfields.h b/include/asterisk/stringfields.h
new file mode 100644
index 000000000..e1b0265aa
--- /dev/null
+++ b/include/asterisk/stringfields.h
@@ -0,0 +1,391 @@
+/*
+ * 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(name);
+ AST_STRING_FIELD(address);
+ AST_STRING_FIELD(password);
+ );
+ long x2;
+ };
+ \endcode
+
+ When an instance of this structure is allocated, the fields
+ (and the pool of storage for them) must be initialized:
+
+ \code
+ struct sample_fields *sample;
+
+ sample = calloc(1, sizeof(*sample));
+ if (sample) {
+ if (ast_string_field_init(sample, 256)) {
+ free(sample);
+ sample = NULL;
+ }
+ }
+
+ if (!sample) {
+ ...
+ }
+ \endcode
+
+ Fields will default to pointing to an empty string, and will
+ revert to that when ast_string_field_free() is called. This means
+ that a string field will \b never contain NULL.
+
+ Using the fields is much like using regular 'char *' fields
+ in the structure, except that writing into them must be done
+ using wrapper macros defined in this file.
+
+ Storing simple values into fields can be done using ast_string_field_set();
+ more complex values (using printf-style format strings) can be stored
+ using ast_string_field_build().
+
+ When the structure instance is no longer needed, the fields
+ and their storage pool must be freed:
+
+ \code
+ ast_string_field_free_memory(sample);
+ free(sample);
+ \endcode
+*/
+
+#ifndef _ASTERISK_STRINGFIELDS_H
+#define _ASTERISK_STRINGFIELDS_H
+
+#include <string.h>
+#include <stdarg.h>
+#include <stddef.h>
+
+#include "asterisk/inline_api.h"
+#include "asterisk/compiler.h"
+#include "asterisk/compat.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
+*/
+struct ast_string_field_mgr {
+ struct ast_string_field_pool *pool; /*!< the address of the pool's structure */
+ size_t size; /*!< the total size of the current pool */
+ size_t space; /*!< the space available in the current pool */
+ size_t used; /*!< the space used in the current pool */
+};
+
+/*!
+ \internal
+ \brief Initialize a field pool manager and fields
+ \param mgr Pointer to the pool manager structure
+ \param size Amount of storage to allocate
+ \param fields Pointer to the first entry of the field array
+ \param num_fields Number of fields in the array
+ \return 0 on success, non-zero on failure
+*/
+int __ast_string_field_init(struct ast_string_field_mgr *mgr, size_t size,
+ ast_string_field *fields, int num_fields);
+
+/*!
+ \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
+ \param num_fields Number of fields in the 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, size_t needed,
+ ast_string_field *fields, int num_fields);
+
+/*!
+ \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 num_fields Number of fields in the array
+ \param index Index position of the field within the structure
+ \param format printf-style format string
+ \return nothing
+*/
+void __ast_string_field_index_build(struct ast_string_field_mgr *mgr,
+ ast_string_field *fields, int num_fields,
+ int index, const char *format, ...) __attribute__((format(printf, 5, 6)));
+
+/*!
+ \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 num_fields Number of fields in the array
+ \param index Index position of the 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_index_build_va(struct ast_string_field_mgr *mgr,
+ ast_string_field *fields, int num_fields,
+ int index, const char *format, va_list a1, va_list a2) __attribute__((format(printf, 5, 0)));
+
+/*!
+ \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
+*/
+#define AST_DECLARE_STRING_FIELDS(field_list) \
+ ast_string_field __begin_field[0]; \
+ field_list \
+ ast_string_field __end_field[0]; \
+ struct ast_string_field_mgr __field_mgr
+
+/*!
+ \brief Get the number of string fields in a structure
+ \param x Pointer to a structure containing fields
+ \return the number of fields in the structure's definition
+*/
+#define ast_string_field_count(x) \
+ (offsetof(typeof(*(x)), __end_field) - offsetof(typeof(*(x)), __begin_field)) / sizeof(ast_string_field)
+
+/*!
+ \brief Get the index of a field in a structure
+ \param x Pointer to a structure containing fields
+ \param field Name of the field to locate
+ \return the position (index) of the field within the structure's
+ array of fields
+*/
+#define ast_string_field_index(x, field) \
+ (offsetof(typeof(*x), field) - offsetof(typeof(*x), __begin_field)) / sizeof(ast_string_field)
+
+/*!
+ \brief Initialize a field pool and fields
+ \param x Pointer to a structure containing fields
+ \param size Amount of storage to allocate
+ \return 0 on success, non-zero on failure
+*/
+#define ast_string_field_init(x, size) \
+ __ast_string_field_init(&(x)->__field_mgr, size, &(x)->__begin_field[0], ast_string_field_count(x))
+
+/*!
+ \brief Set a field to a simple string value
+ \param x Pointer to a structure containing fields
+ \param index Index position of the field within the structure
+ \param data String value to be copied into the field
+ \return nothing
+*/
+#define ast_string_field_index_set(x, index, data) do { \
+ char *__zz__ = (char*) (x)->__begin_field[index]; \
+ char *__data__ = (char*) data; \
+ size_t __dlen__ = strlen(__data__) + 1; \
+ if ( __dlen__ == 1 ) {\
+ (x)->__begin_field[index] = __ast_string_field_empty; \
+ } else { \
+ if ((__zz__[0] != 0) && (__dlen__ <= (strlen(__zz__) + 1))) { \
+ memcpy(__zz__, __data__, __dlen__); \
+ } else { \
+ if (((x)->__begin_field[index] = __ast_string_field_alloc_space(&(x)->__field_mgr, __dlen__, &(x)->__begin_field[0], ast_string_field_count(x)))) { \
+ char *__yy__ = (char *) (x)->__begin_field[index]; \
+ memcpy(__yy__, __data__, __dlen__); \
+ } \
+ } \
+ } \
+ } while (0)
+
+#define ast_string_field_index_logset(x, index, data, logstr) do { \
+ char *__zz__ = (char*) (x)->__begin_field[index]; \
+ char *__data__ = (char*) data; \
+ size_t __dlen__ = strlen(__data__) + 1; \
+ if ( __dlen__ == 1 ) {\
+ (x)->__begin_field[index] = __ast_string_field_empty; \
+ } else { \
+ if ((__zz__[0] != 0) && (__dlen__ <= strlen(__zz__) + 1)) { \
+ ast_verbose("%s: ======replacing '%s' with '%s'\n", logstr, __zz__, __data__); \
+ memcpy(__zz__, __data__, __dlen__); \
+ } else { \
+ if (((x)->__begin_field[index] = __ast_string_field_alloc_space(&(x)->__field_mgr, __dlen__, &(x)->__begin_field[0], ast_string_field_count(x)))) \
+ ast_verbose("%s: ++++++allocating room for '%s' to replace '%s'\n", logstr, __data__, __zz__); \
+ memcpy((char*) (x)->__begin_field[index], __data__, __dlen__); \
+ } \
+ } \
+ } 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) \
+ ast_string_field_index_set(x, ast_string_field_index(x, field), data)
+
+#define ast_string_field_logset(x, field, data, logstr) \
+ ast_string_field_index_logset(x, ast_string_field_index(x, field), data, logstr)
+
+/*!
+ \brief Set a field to a complex (built) value
+ \param x Pointer to a structure containing fields
+ \param index Index position of the field within the structure
+ \param fmt printf-style format string
+ \param args Arguments for format string
+ \return nothing
+*/
+#define ast_string_field_index_build(x, index, fmt, args...) \
+ __ast_string_field_index_build(&(x)->__field_mgr, &(x)->__begin_field[0], ast_string_field_count(x), index, fmt, args)
+
+/*!
+ \brief Set a field to a complex (built) value with prebuilt va_lists.
+ \param x Pointer to a structure containing fields
+ \param index Index position of the 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_index_build_va(x, index, fmt, args1, args2) \
+ __ast_string_field_index_build_va(&(x)->__field_mgr, &(x)->__begin_field[0], ast_string_field_count(x), index, 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 args Arguments for format string
+ \return nothing
+*/
+#define ast_string_field_build(x, field, fmt, args...) \
+ ast_string_field_index_build(x, ast_string_field_index(x, field), 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 argslist a va_list of the args
+ \return nothing
+*/
+#define ast_string_field_build_va(x, field, fmt, args1, args2) \
+ ast_string_field_index_build_va(x, ast_string_field_index(x, field), fmt, args1, args2)
+
+/*!
+ \brief Free a field's value.
+ \param x Pointer to a structure containing fields
+ \param index Index position of the field within the structure
+ \return nothing
+
+ \note Because of the storage pool used, the memory
+ occupied by the field's value is \b not recovered; the field
+ pointer is just changed to point to an empty string.
+*/
+#define ast_string_field_index_free(x, index) do { \
+ (x)->__begin_field[index] = __ast_string_field_empty; \
+ } while(0)
+
+/*!
+ \brief Free a field's value.
+ \param x Pointer to a structure containing fields
+ \param field Name of the field to free
+ \return nothing
+
+ \note Because of the storage pool used, the memory
+ occupied by the field's value is \b not recovered; the field
+ pointer is just changed to point to an empty string.
+*/
+#define ast_string_field_free(x, field) \
+ ast_string_field_index_free(x, ast_string_field_index(x, field))
+
+/*!
+ \brief Free the stringfield storage pools attached to a structure
+ \param x Pointer to a structure containing fields
+ \return nothing
+
+ After calling this macro, fields can no longer be accessed in
+ structure; it should only be called immediately before freeing
+ the structure itself.
+*/
+#define ast_string_field_free_memory(x) do { \
+ struct ast_string_field_pool *this, *prev; \
+ for (this = (x)->__field_mgr.pool; this; this = prev) { \
+ prev = this->prev; \
+ free(this); \
+ } \
+ } while(0)
+
+/*!
+ \brief Free the stringfields in a structure
+ \param x Pointer to a structure containing fields
+ \return nothing
+
+ After calling this macro, the most recently allocated pool
+ attached to the structure will be available for use by
+ stringfields again.
+*/
+#define ast_string_field_reset_all(x) do { \
+ int index; \
+ for (index = 0; index < ast_string_field_count(x); index++) \
+ ast_string_field_index_free(x, index); \
+ (x)->__field_mgr.used = 0; \
+ (x)->__field_mgr.space = (x)->__field_mgr.size; \
+ } while(0)
+
+#endif /* _ASTERISK_STRINGFIELDS_H */
diff --git a/include/asterisk/strings.h b/include/asterisk/strings.h
new file mode 100644
index 000000000..c800d532e
--- /dev/null
+++ b/include/asterisk/strings.h
@@ -0,0 +1,304 @@
+/*
+ * 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 <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <ctype.h>
+
+#include "asterisk/inline_api.h"
+#include "asterisk/compiler.h"
+#include "asterisk/compat.h"
+
+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 Gets a pointer to the first non-whitespace character in a string.
+ \param ast_skip_blanks function being used
+ \param 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_trim_blanks function being used
+ \param 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
+ \param 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 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 Size-limited null-terminating string copy.
+ \param ast_copy_string function being used
+ \param dst The destination buffer.
+ \param src The source string
+ \param 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
+
+ This is a wrapper for snprintf, that properly handles the buffer pointer
+ and buffer space available.
+
+ \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
+ \return 0 on success, 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) __attribute__((format(printf, 3, 0)));
+
+/*! 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".
+ *
+ * Returns 0 if val is a NULL pointer, -1 if "true", and 0 otherwise.
+ */
+int ast_true(const char *val);
+
+/*! 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".
+ *
+ * Returns 0 if val is a NULL pointer, -1 if "false", and 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)
+ \return zero on success, non-zero on failure
+*/
+int ast_get_time_t(const char *src, time_t *dst, time_t _default, int *consumed);
+
+/* The realloca lets us ast_restrdupa(), but you can't mix any other ast_strdup calls! */
+
+struct ast_realloca {
+ char *ptr;
+ int alloclen;
+};
+
+#define ast_restrdupa(ra, s) \
+ ({ \
+ if ((ra)->ptr && strlen(s) + 1 < (ra)->alloclen) { \
+ strcpy((ra)->ptr, s); \
+ } else { \
+ (ra)->ptr = alloca(strlen(s) + 1 - (ra)->alloclen); \
+ if ((ra)->ptr) (ra)->alloclen = strlen(s) + 1; \
+ } \
+ (ra)->ptr; \
+ })
+
+/*!
+ * \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);
+}
+
+/*!
+ * \brief Compute a hash value on a case-insensitive string
+ *
+ * Uses the same hash algorithm as ast_str_hash, but converts
+ * all characters to lowercase prior to computing a hash. This
+ * allows for easy case-insensitive lookups in a hash table.
+ */
+static force_inline int ast_str_case_hash(const char *str)
+{
+ int hash = 5381;
+
+ while (*str) {
+ hash = hash * 33 ^ tolower(*str++);
+ }
+
+ return abs(hash);
+}
+
+#endif /* _ASTERISK_STRINGS_H */
diff --git a/include/asterisk/tdd.h b/include/asterisk/tdd.h
new file mode 100644
index 000000000..bdd02bb40
--- /dev/null
+++ b/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 diable 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);
+
+#endif /* _ASTERISK_TDD_H */
diff --git a/include/asterisk/term.h b/include/asterisk/term.h
new file mode 100644
index 000000000..3b454ce2c
--- /dev/null
+++ b/include/asterisk/term.h
@@ -0,0 +1,76 @@
+/*
+ * 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
+#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
+
+#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/include/asterisk/threadstorage.h b/include/asterisk/threadstorage.h
new file mode 100644
index 000000000..3829b8f1a
--- /dev/null
+++ b/include/asterisk/threadstorage.h
@@ -0,0 +1,498 @@
+/*
+ * 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
+*/
+
+#ifndef ASTERISK_THREADSTORAGE_H
+#define ASTERISK_THREADSTORAGE_H
+
+#include <pthread.h>
+
+#include "asterisk/utils.h"
+#include "asterisk/inline_api.h"
+
+/*!
+ * \brief data for a thread locally stored variable
+ */
+struct ast_threadstorage {
+ /*! Ensure that the key is only initialized by one thread */
+ pthread_once_t once;
+ /*! The key used to retrieve this thread's data */
+ pthread_key_t key;
+ /*! The function that initializes the key */
+ void (*key_init)(void);
+};
+
+#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
+ * \arg name_init This is a name used to create the function that gets called
+ * to initialize this thread storage. It can be anything since it will not
+ * be referred to anywhere else
+ *
+ * This macro would be used to declare an instance of thread storage in a file.
+ *
+ * Example usage:
+ * \code
+ * AST_THREADSTORAGE(my_buf, my_buf_init);
+ * \endcode
+ */
+#define AST_THREADSTORAGE(name, name_init) \
+ AST_THREADSTORAGE_CUSTOM(name, name_init, ast_free)
+
+#if !defined(DEBUG_THREADLOCALS)
+#define AST_THREADSTORAGE_CUSTOM(name, name_init, cleanup) \
+static void name_init(void); \
+static struct ast_threadstorage name = { \
+ .once = THREADSTORAGE_ONCE_INIT, \
+ .key_init = name_init, \
+}; \
+static void name_init(void) \
+{ \
+ pthread_key_create(&(name).key, cleanup); \
+}
+#else /* defined(DEBUG_THREADLOCALS) */
+#define AST_THREADSTORAGE_CUSTOM(name, name_init, cleanup) \
+static void name_init(void); \
+static struct ast_threadstorage name = { \
+ .once = THREADSTORAGE_ONCE_INIT, \
+ .key_init = name_init, \
+}; \
+static void __cleanup_##name(void *data) \
+{ \
+ __ast_threadstorage_object_remove(data); \
+ cleanup(data); \
+} \
+static void name_init(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;
+ 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;
+ 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) */
+
+/*!
+ * \brief A dynamic length string
+ */
+struct ast_dynamic_str {
+ /* The current maximum length of the string */
+ size_t len;
+ /* The string buffer */
+ char str[0];
+};
+
+/*!
+ * \brief Create a 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_dynamic_str * attribute_malloc ast_dynamic_str_create(size_t init_len),
+{
+ struct ast_dynamic_str *buf;
+
+ if (!(buf = ast_calloc(1, sizeof(*buf) + init_len)))
+ return NULL;
+
+ buf->len = init_len;
+
+ return 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 storaged 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_dynamic_str *buf;
+ *
+ * if (!(buf = ast_dynamic_str_thread_get(&my_str, MY_STR_INIT_SIZE)))
+ * return;
+ * ...
+ * }
+ * \endcode
+ */
+#if !defined(DEBUG_THREADLOCALS)
+AST_INLINE_API(
+struct ast_dynamic_str *ast_dynamic_str_thread_get(struct ast_threadstorage *ts,
+ size_t init_len),
+{
+ struct ast_dynamic_str *buf;
+
+ if (!(buf = ast_threadstorage_get(ts, sizeof(*buf) + init_len)))
+ return NULL;
+
+ if (!buf->len)
+ buf->len = init_len;
+
+ return buf;
+}
+)
+#else /* defined(DEBUG_THREADLOCALS) */
+AST_INLINE_API(
+struct ast_dynamic_str *__ast_dynamic_str_thread_get(struct ast_threadstorage *ts,
+ size_t init_len, const char *file, const char *function, unsigned int line),
+{
+ struct ast_dynamic_str *buf;
+
+ if (!(buf = __ast_threadstorage_get(ts, sizeof(*buf) + init_len, file, function, line)))
+ return NULL;
+
+ if (!buf->len)
+ buf->len = init_len;
+
+ return buf;
+}
+)
+
+#define ast_dynamic_str_thread_get(ts, init_len) __ast_dynamic_str_thread_get(ts, init_len, __FILE__, __PRETTY_FUNCTION__, __LINE__)
+#endif /* defined(DEBUG_THREADLOCALS) */
+
+/*!
+ * \brief Error codes from ast_dynamic_str_thread_build_va()
+ */
+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_dynamic_str_thread_build_va() needs to be called again after
+ * a va_end() and va_start().
+ */
+ AST_DYNSTR_BUILD_RETRY = -2
+};
+
+/*!
+ * \brief Set a thread locally stored dynamic string from a va_list
+ *
+ * \arg buf This is the address of a pointer to an ast_dynamic_str which should
+ * have been retrieved using ast_dynamic_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.
+ * \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 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:
+ * \code
+ * AST_THREADSTORAGE(my_str, my_str_init);
+ * #define MY_STR_INIT_SIZE 128
+ * ...
+ * void my_func(const char *fmt, ...)
+ * {
+ * struct ast_dynamic_str *buf;
+ * va_list ap;
+ *
+ * if (!(buf = ast_dynamic_str_thread_get(&my_str, MY_STR_INIT_SIZE)))
+ * return;
+ * ...
+ * va_start(fmt, ap);
+ * ast_dynamic_str_thread_set_va(&buf, 0, &my_str, fmt, ap);
+ * va_end(ap);
+ *
+ * printf("This is the string we just built: %s\n", buf->str);
+ * ...
+ * }
+ * \endcode
+ */
+#define ast_dynamic_str_thread_set_va(buf, max_len, ts, fmt, ap) \
+ ({ \
+ int __res; \
+ while ((__res = ast_dynamic_str_thread_build_va(buf, max_len, \
+ ts, 0, fmt, ap)) == AST_DYNSTR_BUILD_RETRY) { \
+ va_end(ap); \
+ va_start(ap, fmt); \
+ } \
+ (__res); \
+ })
+
+/*!
+ * \brief Append to a thread local dynamic string using a va_list
+ *
+ * The arguments, return values, and usage of this are the same as those for
+ * ast_dynamic_str_thread_set_va(). However, instead of setting a new value
+ * for the string, this will append to the current value.
+ */
+#define ast_dynamic_str_thread_append_va(buf, max_len, ts, fmt, ap) \
+ ({ \
+ int __res; \
+ while ((__res = ast_dynamic_str_thread_build_va(buf, max_len, \
+ ts, 1, fmt, ap)) == AST_DYNSTR_BUILD_RETRY) { \
+ va_end(ap); \
+ va_start(ap, fmt); \
+ } \
+ (__res); \
+ })
+
+/*!
+ * \brief Core functionality of ast_dynamic_str_thread_(set|append)_va
+ *
+ * The arguments to this function are the same as those described for
+ * ast_dynamic_str_thread_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.
+ */
+int ast_dynamic_str_thread_build_va(struct ast_dynamic_str **buf, size_t max_len,
+ struct ast_threadstorage *ts, int append, const char *fmt, va_list ap) __attribute__((format(printf, 5, 0)));
+
+/*!
+ * \brief Set a thread locally stored dynamic string using variable arguments
+ *
+ * \arg buf This is the address of a pointer to an ast_dynamic_str which should
+ * have been retrieved using ast_dynamic_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.
+ * \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 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.
+ *
+ * Example usage:
+ * \code
+ * AST_THREADSTORAGE(my_str, my_str_init);
+ * #define MY_STR_INIT_SIZE 128
+ * ...
+ * void my_func(int arg1, int arg2)
+ * {
+ * struct ast_dynamic_str *buf;
+ * va_list ap;
+ *
+ * if (!(buf = ast_dynamic_str_thread_get(&my_str, MY_STR_INIT_SIZE)))
+ * return;
+ * ...
+ * ast_dynamic_str_thread_set(&buf, 0, &my_str, "arg1: %d arg2: %d\n",
+ * arg1, arg2);
+ *
+ * printf("This is the string we just built: %s\n", buf->str);
+ * ...
+ * }
+ * \endcode
+ */
+AST_INLINE_API(
+int __attribute__((format(printf, 4, 5))) ast_dynamic_str_thread_set(
+ struct ast_dynamic_str **buf, size_t max_len,
+ struct ast_threadstorage *ts, const char *fmt, ...),
+{
+ int res;
+ va_list ap;
+
+ va_start(ap, fmt);
+ res = ast_dynamic_str_thread_set_va(buf, max_len, ts, 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_dynamic_str_thread_set(). However, instead of setting a new value for
+ * the string, this function appends to the current value.
+ */
+AST_INLINE_API(
+int __attribute__((format(printf, 4, 5))) ast_dynamic_str_thread_append(
+ struct ast_dynamic_str **buf, size_t max_len,
+ struct ast_threadstorage *ts, const char *fmt, ...),
+{
+ int res;
+ va_list ap;
+
+ va_start(ap, fmt);
+ res = ast_dynamic_str_thread_append_va(buf, max_len, ts, fmt, ap);
+ va_end(ap);
+
+ return res;
+}
+)
+
+/*!
+ * \brief Set a dynamic string
+ *
+ * \arg buf This is the address of a pointer to an ast_dynamic_str. 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.
+ *
+ * \return The return value of this function is the same as that of the printf
+ * family of functions.
+ */
+AST_INLINE_API(
+int __attribute__((format(printf, 3, 4))) ast_dynamic_str_set(
+ struct ast_dynamic_str **buf, size_t max_len,
+ const char *fmt, ...),
+{
+ int res;
+ va_list ap;
+
+ va_start(ap, fmt);
+ res = ast_dynamic_str_thread_set_va(buf, max_len, NULL, fmt, ap);
+ va_end(ap);
+
+ return res;
+}
+)
+
+/*!
+ * \brief Append to a dynatic string
+ *
+ * The arguments, return values, and usage of this function are the same as
+ * ast_dynamic_str_set(). However, this function appends to the string instead
+ * of setting a new value.
+ */
+AST_INLINE_API(
+int __attribute__((format(printf, 3, 4))) ast_dynamic_str_append(
+ struct ast_dynamic_str **buf, size_t max_len,
+ const char *fmt, ...),
+{
+ int res;
+ va_list ap;
+
+ va_start(ap, fmt);
+ res = ast_dynamic_str_thread_append_va(buf, max_len, NULL, fmt, ap);
+ va_end(ap);
+
+ return res;
+}
+)
+
+#endif /* ASTERISK_THREADSTORAGE_H */
diff --git a/include/asterisk/time.h b/include/asterisk/time.h
new file mode 100644
index 000000000..92a5346a5
--- /dev/null
+++ b/include/asterisk/time.h
@@ -0,0 +1,144 @@
+/*
+ * 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
+
+#include <sys/time.h>
+#include <stdlib.h>
+
+#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 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/include/asterisk/tonezone_compat.h b/include/asterisk/tonezone_compat.h
new file mode 100644
index 000000000..40b35605c
--- /dev/null
+++ b/include/asterisk/tonezone_compat.h
@@ -0,0 +1,35 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2008, 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.
+ */
+
+/*!
+ * \file
+ * \brief Find tonezone header in the right place (DAHDI or Zaptel)
+ */
+
+#ifndef TONEZONE_COMPAT_H
+#define TONEZONE_COMPAT_H
+
+#if defined(HAVE_ZAPTEL)
+
+#include <zaptel/tonezone.h>
+
+#elif defined(HAVE_DAHDI)
+
+#include <dahdi/tonezone.h>
+
+#endif
+
+#endif /* TONEZONE_COMPAT_H */
diff --git a/include/asterisk/transcap.h b/include/asterisk/transcap.h
new file mode 100644
index 000000000..5da8329dc
--- /dev/null
+++ b/include/asterisk/transcap.h
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+#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/include/asterisk/translate.h b/include/asterisk/translate.h
new file mode 100644
index 000000000..a81d0072a
--- /dev/null
+++ b/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.
+ */
+
+#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 coded 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 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
+ *
+ * Also, for the sake of ABI compatability, a magic value of -1 in this
+ * field means that the pvt has been requested to be destroyed, but is
+ * pending destruction until ast_translate_frame_freed() gets called.
+ */
+ 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;
+};
+
+/*! \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);
+#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 that 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/include/asterisk/udptl.h b/include/asterisk/udptl.h
new file mode 100644
index 000000000..1615a19ef
--- /dev/null
+++ b/include/asterisk/udptl.h
@@ -0,0 +1,120 @@
+/*
+ * 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.
+ */
+
+#ifndef _ASTERISK_UDPTL_H
+#define _ASTERISK_UDPTL_H
+
+#include "asterisk/frame.h"
+#include "asterisk/io.h"
+#include "asterisk/sched.h"
+#include "asterisk/channel.h"
+
+#include <netinet/in.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 {
+ /* Get UDPTL struct, or NULL if unwilling to transfer */
+ struct ast_udptl *(*get_udptl_info)(struct ast_channel *chan);
+ /* Set UDPTL peer */
+ int (* const set_udptl_peer)(struct ast_channel *chan, struct ast_udptl *peer);
+ const char * const type;
+ struct ast_udptl_protocol *next;
+};
+
+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_settos(struct ast_udptl *udptl, int tos);
+
+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/include/asterisk/ulaw.h b/include/asterisk/ulaw.h
new file mode 100644
index 000000000..d9ab0d178
--- /dev/null
+++ b/include/asterisk/ulaw.h
@@ -0,0 +1,43 @@
+/*
+ * 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
+
+/*! Init the ulaw conversion stuff */
+/*!
+ * To init the ulaw to slinear conversion stuff, this needs to be run.
+ */
+void ast_ulaw_init(void);
+
+/*! converts signed linear to mulaw */
+/*!
+ */
+extern unsigned char __ast_lin2mu[16384];
+
+/*! help */
+extern short __ast_mulaw[256];
+
+#define AST_LIN2MU(a) (__ast_lin2mu[((unsigned short)(a)) >> 2])
+#define AST_MULAW(a) (__ast_mulaw[(a)])
+
+#endif /* _ASTERISK_ULAW_H */
diff --git a/include/asterisk/unaligned.h b/include/asterisk/unaligned.h
new file mode 100644
index 000000000..16791d6f0
--- /dev/null
+++ b/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(void *p)
+{
+ struct { unsigned int d; } __attribute__((packed)) *pp = (void *)p;
+
+ return pp->d;
+}
+static inline unsigned short get_unaligned_uint16(void *p)
+{
+ struct { unsigned short d; } __attribute__((packed)) *pp = (void *)p;
+
+ return pp->d;
+}
+
+static inline void put_unaligned_uint32(void *p, unsigned int datum)
+{
+ struct { unsigned int d; } __attribute__((packed)) *pp = (void *)p;
+
+ pp->d = datum;
+}
+
+static inline void put_unaligned_uint16(void *p, unsigned short datum)
+{
+ struct { unsigned short d; } __attribute__((packed)) *pp = (void *)p;
+
+ pp->d = datum;
+}
+#elif defined(SOLARIS) && defined(__sparc__)
+static inline unsigned int get_unaligned_uint32(void *p)
+{
+ unsigned char *cp = p;
+
+ return (cp[0] << 24) | (cp[1] << 16) | (cp[2] << 8) | cp[3];
+}
+
+static inline unsigned short get_unaligned_uint16(void *p)
+{
+ 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/include/asterisk/utils.h b/include/asterisk/utils.h
new file mode 100644
index 000000000..44da65e70
--- /dev/null
+++ b/include/asterisk/utils.h
@@ -0,0 +1,578 @@
+/*
+ * 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/compat.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <netinet/in.h>
+#include <arpa/inet.h> /* we want to override inet_ntoa */
+#include <netdb.h>
+#include <limits.h>
+#include <time.h> /* we want to override localtime_r */
+#include <unistd.h>
+
+#include "asterisk/lock.h"
+#include "asterisk/time.h"
+#include "asterisk/strings.h"
+#include "asterisk/logger.h"
+#include "asterisk/compiler.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)
+
+/* 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
+
+struct ast_flags {
+ unsigned int flags;
+};
+
+struct ast_hostent {
+ struct hostent hp;
+ char buf[1024];
+};
+
+struct hostent *ast_gethostbyname(const char *host, struct ast_hostent *hp);
+
+/* ast_md5_hash
+ \brief Produces MD5 hash based on input string */
+void ast_md5_hash(char *output, char *input);
+/* ast_sha1_hash
+ \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);
+int ast_base64encode(char *dst, const unsigned char *src, int srclen, int max);
+int ast_base64decode(unsigned char *dst, const char *src, int max);
+
+/*! ast_uri_encode
+ \brief Turn text string to URI-encoded %XX version
+ 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_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;
+}
+
+/*!
+ * \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__
+
+#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);
+
+/*! ast_carefulwrite
+ \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);
+
+/*! 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));
+}
+
+#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);
+
+#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_background(a, b, c, d) ast_pthread_create_stack(a, b, c, d, \
+ AST_BACKGROUND_STACKSIZE, \
+ __FILE__, __FUNCTION__, \
+ __LINE__, #c)
+
+/*!
+ \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);
+
+#ifdef linux
+#define ast_random random
+#else
+long int ast_random(void);
+#endif
+
+/*!
+ * \brief free() wrapper
+ *
+ * ast_free 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(void *ptr) attribute_unused;
+static void ast_free(void *ptr)
+{
+ free(ptr);
+}
+#else
+#define ast_free 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__)
+
+int _ast_asprintf(char **ret, const char *file, int lineno, const char *func, const char *fmt, ...) __attribute__((format(printf, 5, 6)));
+
+/*!
+ * \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 __attribute__((format(printf, 5, 0))) _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,...) asprintf(a,b,__VA_ARGS__)
+#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);
+
+#define ARRAY_LEN(a) (sizeof(a) / sizeof(a[0]))
+
+#ifdef AST_DEVMODE
+#define ast_assert(a) _ast_assert(a, # a, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+static void force_inline _ast_assert(int condition, const char *condition_str,
+ const char *file, int line, const char *function)
+{
+ if (__builtin_expect(!condition, 1)) {
+ /* Attempt to put it into the logger, but hope that at least someone saw the
+ * message on stderr ... */
+ ast_log(LOG_ERROR, "FRACK!, Failed assertion %s (%d) at line %d in %s of %s\n",
+ condition_str, condition, line, function, file);
+ fprintf(stderr, "FRACK!, Failed assertion %s (%d) at line %d in %s of %s\n",
+ condition_str, condition, line, function, file);
+ /* Give the logger a chance to get the message out, just in case we abort(), or
+ * Asterisk crashes due to whatever problem just happened after we exit ast_assert(). */
+ usleep(1);
+#ifdef DO_CRASH
+ abort();
+ /* Just in case abort() doesn't work or something else super silly,
+ * and for Qwell's amusement. */
+ *((int*)0)=0;
+#endif
+ }
+}
+#else
+#define ast_assert(a)
+#endif
+
+#endif /* _ASTERISK_UTILS_H */
diff --git a/include/jitterbuf.h b/include/jitterbuf.h
new file mode 100644
index 000000000..45ec06f2d
--- /dev/null
+++ b/include/jitterbuf.h
@@ -0,0 +1,162 @@
+/*
+ * jitterbuf: an application-independent jitterbuffer
+ *
+ * Copyrights:
+ * Copyright (C) 2004-2005, Horizon Wimba, Inc.
+ *
+ * Contributors:
+ * Steve Kann <stevek@stevek.com>
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU Lesser (Library) General Public License
+ *
+ * Copyright on this file is disclaimed to Digium for inclusion in Asterisk
+ */
+
+#ifndef _JITTERBUF_H_
+#define _JITTERBUF_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* configuration constants */
+ /* Number of historical timestamps to use in calculating jitter and drift */
+#define JB_HISTORY_SZ 500
+ /* what percentage of timestamps should we drop from the history when we examine it;
+ * this might eventually be something made configurable */
+#define JB_HISTORY_DROPPCT 3
+ /* the maximum droppct we can handle (say it was configurable). */
+#define JB_HISTORY_DROPPCT_MAX 4
+ /* the size of the buffer we use to keep the top and botton timestamps for dropping */
+#define JB_HISTORY_MAXBUF_SZ JB_HISTORY_SZ * JB_HISTORY_DROPPCT_MAX / 100
+ /* amount of additional jitterbuffer adjustment */
+#define JB_TARGET_EXTRA 40
+ /* ms between growing and shrinking; may not be honored if jitterbuffer runs out of space */
+#define JB_ADJUST_DELAY 40
+
+enum jb_return_code {
+ /* return codes */
+ JB_OK, /* 0 */
+ JB_EMPTY, /* 1 */
+ JB_NOFRAME, /* 2 */
+ JB_INTERP, /* 3 */
+ JB_DROP, /* 4 */
+ JB_SCHED /* 5 */
+};
+
+enum jb_frame_type {
+ /* frame types */
+ JB_TYPE_CONTROL, /* 0 */
+ JB_TYPE_VOICE, /* 1 */
+ JB_TYPE_VIDEO, /* 2 - reserved */
+ JB_TYPE_SILENCE /* 3 */
+};
+
+typedef struct jb_conf {
+ /* settings */
+ long max_jitterbuf; /* defines a hard clamp to use in setting the jitter buffer delay */
+ long resync_threshold; /* the jb will resync when delay increases to (2 * jitter) + this param */
+ long max_contig_interp; /* the max interp frames to return in a row */
+} jb_conf;
+
+typedef struct jb_info {
+ jb_conf conf;
+
+ /* statistics */
+ long frames_in; /* number of frames input to the jitterbuffer.*/
+ long frames_out; /* number of frames output from the jitterbuffer.*/
+ long frames_late; /* number of frames which were too late, and dropped.*/
+ long frames_lost; /* number of missing frames.*/
+ long frames_dropped; /* number of frames dropped (shrinkage) */
+ long frames_ooo; /* number of frames received out-of-order */
+ long frames_cur; /* number of frames presently in jb, awaiting delivery.*/
+ long jitter; /* jitter measured within current history interval*/
+ long min; /* minimum lateness within current history interval */
+ long current; /* the present jitterbuffer adjustment */
+ long target; /* the target jitterbuffer adjustment */
+ long losspct; /* recent lost frame percentage (* 1000) */
+ long next_voice_ts; /* the ts of the next frame to be read from the jb - in receiver's time */
+ long last_voice_ms; /* the duration of the last voice frame */
+ long silence_begin_ts; /* the time of the last CNG frame, when in silence */
+ long last_adjustment; /* the time of the last adjustment */
+ long last_delay; /* the last now added to history */
+ long cnt_delay_discont; /* the count of discontinuous delays */
+ long resync_offset; /* the amount to offset ts to support resyncs */
+ long cnt_contig_interp; /* the number of contiguous interp frames returned */
+} jb_info;
+
+typedef struct jb_frame {
+ void *data; /* the frame data */
+ long ts; /* the relative delivery time expected */
+ long ms; /* the time covered by this frame, in sec/8000 */
+ enum jb_frame_type type; /* the type of frame */
+ struct jb_frame *next, *prev;
+} jb_frame;
+
+typedef struct jitterbuf {
+ jb_info info;
+
+ /* history */
+ long history[JB_HISTORY_SZ]; /* history */
+ int hist_ptr; /* points to index in history for next entry */
+ long hist_maxbuf[JB_HISTORY_MAXBUF_SZ]; /* a sorted buffer of the max delays (highest first) */
+ long hist_minbuf[JB_HISTORY_MAXBUF_SZ]; /* a sorted buffer of the min delays (lowest first) */
+ int hist_maxbuf_valid; /* are the "maxbuf"/minbuf valid? */
+ unsigned int dropem:1; /* flag to indicate dropping frames (overload) */
+
+ jb_frame *frames; /* queued frames */
+ jb_frame *free; /* free frames (avoid malloc?) */
+} jitterbuf;
+
+
+/* new jitterbuf */
+jitterbuf * jb_new(void);
+
+/* destroy jitterbuf */
+void jb_destroy(jitterbuf *jb);
+
+/* reset jitterbuf */
+/* NOTE: The jitterbuffer should be empty before you call this, otherwise
+ * you will leak queued frames, and some internal structures */
+void jb_reset(jitterbuf *jb);
+
+/* queue a frame data=frame data, timings (in ms): ms=length of frame (for voice), ts=ts (sender's time)
+ * now=now (in receiver's time) return value is one of
+ * JB_OK: Frame added. Last call to jb_next() still valid
+ * JB_DROP: Drop this frame immediately
+ * JB_SCHED: Frame added. Call jb_next() to get a new time for the next frame
+ */
+enum jb_return_code jb_put(jitterbuf *jb, void *data, const enum jb_frame_type type, long ms, long ts, long now);
+
+/* get a frame for time now (receiver's time) return value is one of
+ * JB_OK: You've got frame!
+ * JB_DROP: Here's an audio frame you should just drop. Ask me again for this time..
+ * JB_NOFRAME: There's no frame scheduled for this time.
+ * JB_INTERP: Please interpolate an interpl-length frame for this time (either we need to grow, or there was a lost frame)
+ * JB_EMPTY: The jb is empty.
+ */
+enum jb_return_code jb_get(jitterbuf *jb, jb_frame *frame, long now, long interpl);
+
+/* unconditionally get frames from jitterbuf until empty */
+enum jb_return_code jb_getall(jitterbuf *jb, jb_frame *frameout);
+
+/* when is the next frame due out, in receiver's time (0=EMPTY)
+ * This value may change as frames are added (esp non-audio frames) */
+long jb_next(jitterbuf *jb);
+
+/* get jitterbuf info: only "statistics" may be valid */
+enum jb_return_code jb_getinfo(jitterbuf *jb, jb_info *stats);
+
+/* set jitterbuf conf */
+enum jb_return_code jb_setconf(jitterbuf *jb, jb_conf *conf);
+
+typedef void __attribute__((format(printf, 1, 2))) (*jb_output_function_t)(const char *fmt, ...);
+void jb_setoutput(jb_output_function_t err, jb_output_function_t warn, jb_output_function_t dbg);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/include/solaris-compat/compat.h b/include/solaris-compat/compat.h
new file mode 100644
index 000000000..b34cf11f4
--- /dev/null
+++ b/include/solaris-compat/compat.h
@@ -0,0 +1,46 @@
+#ifndef _SOLARIS_COMPAT_H
+#define _SOLARIS_COMPAT_H
+
+#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>
+
+#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
+
+char* strsep(char** str, const char* delims);
+int setenv(const char *name, const char *value, int overwrite);
+int unsetenv(const char *name);
+#endif
diff --git a/include/solaris-compat/sys/cdefs.h b/include/solaris-compat/sys/cdefs.h
new file mode 100644
index 000000000..40f76af87
--- /dev/null
+++ b/include/solaris-compat/sys/cdefs.h
@@ -0,0 +1,10 @@
+#ifndef __SYS_CDEFS_H_
+#define __SYS_CDEFS_H_
+
+#define __BEGIN_DECLS
+#define __END_DECLS
+
+#define __P(p) p
+
+
+#endif
diff --git a/include/solaris-compat/sys/queue.h b/include/solaris-compat/sys/queue.h
new file mode 100644
index 000000000..ac273dfe3
--- /dev/null
+++ b/include/solaris-compat/sys/queue.h
@@ -0,0 +1,540 @@
+/*
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)queue.h 8.5 (Berkeley) 8/20/94
+ * $FreeBSD: src/sys/sys/queue.h,v 1.24.2.4 2000/05/05 01:41:41 archie Exp $
+ */
+
+#ifndef _SYS_QUEUE_H_
+#define _SYS_QUEUE_H_
+
+/*
+ * This file defines five types of data structures: singly-linked lists,
+ * singly-linked tail queues, lists, tail queues, and circular queues.
+ *
+ * A singly-linked list is headed by a single forward pointer. The elements
+ * are singly linked for minimum space and pointer manipulation overhead at
+ * the expense of O(n) removal for arbitrary elements. New elements can be
+ * added to the list after an existing element or at the head of the list.
+ * Elements being removed from the head of the list should use the explicit
+ * macro for this purpose for optimum efficiency. A singly-linked list may
+ * only be traversed in the forward direction. Singly-linked lists are ideal
+ * for applications with large datasets and few or no removals or for
+ * implementing a LIFO queue.
+ *
+ * A singly-linked tail queue is headed by a pair of pointers, one to the
+ * head of the list and the other to the tail of the list. The elements are
+ * singly linked for minimum space and pointer manipulation overhead at the
+ * expense of O(n) removal for arbitrary elements. New elements can be added
+ * to the list after an existing element, at the head of the list, or at the
+ * end of the list. Elements being removed from the head of the tail queue
+ * should use the explicit macro for this purpose for optimum efficiency.
+ * A singly-linked tail queue may only be traversed in the forward direction.
+ * Singly-linked tail queues are ideal for applications with large datasets
+ * and few or no removals or for implementing a FIFO queue.
+ *
+ * A list is headed by a single forward pointer (or an array of forward
+ * pointers for a hash table header). The elements are doubly linked
+ * so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before
+ * or after an existing element or at the head of the list. A list
+ * may only be traversed in the forward direction.
+ *
+ * A tail queue is headed by a pair of pointers, one to the head of the
+ * list and the other to the tail of the list. The elements are doubly
+ * linked so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before or
+ * after an existing element, at the head of the list, or at the end of
+ * the list. A tail queue may be traversed in either direction.
+ *
+ * A circle queue is headed by a pair of pointers, one to the head of the
+ * list and the other to the tail of the list. The elements are doubly
+ * linked so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before or after
+ * an existing element, at the head of the list, or at the end of the list.
+ * A circle queue may be traversed in either direction, but has a more
+ * complex end of list detection.
+ *
+ * For details on the use of these macros, see the queue(3) manual page.
+ *
+ *
+ * SLIST LIST STAILQ TAILQ CIRCLEQ
+ * _HEAD + + + + +
+ * _ENTRY + + + + +
+ * _INIT + + + + +
+ * _EMPTY + + + + +
+ * _FIRST + + + + +
+ * _NEXT + + + + +
+ * _PREV - - - + +
+ * _LAST - - + + +
+ * _FOREACH + + + + +
+ * _FOREACH_REVERSE - - - + +
+ * _INSERT_HEAD + + + + +
+ * _INSERT_BEFORE - + - + +
+ * _INSERT_AFTER + + + + +
+ * _INSERT_TAIL - - + + +
+ * _REMOVE_HEAD + - + - -
+ * _REMOVE + + + + +
+ *
+ */
+
+/*
+ * Singly-linked List definitions.
+ */
+#define SLIST_HEAD(name, type) \
+struct name { \
+ struct type *slh_first; /* first element */ \
+}
+
+#define SLIST_HEAD_INITIALIZER(head) \
+ { NULL }
+
+#define SLIST_ENTRY(type) \
+struct { \
+ struct type *sle_next; /* next element */ \
+}
+
+/*
+ * Singly-linked List functions.
+ */
+#define SLIST_EMPTY(head) ((head)->slh_first == NULL)
+
+#define SLIST_FIRST(head) ((head)->slh_first)
+
+#define SLIST_FOREACH(var, head, field) \
+ for((var) = (head)->slh_first; (var); (var) = (var)->field.sle_next)
+
+#define SLIST_INIT(head) { \
+ (head)->slh_first = NULL; \
+}
+
+#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
+ (elm)->field.sle_next = (slistelm)->field.sle_next; \
+ (slistelm)->field.sle_next = (elm); \
+} while (0)
+
+#define SLIST_INSERT_HEAD(head, elm, field) do { \
+ (elm)->field.sle_next = (head)->slh_first; \
+ (head)->slh_first = (elm); \
+} while (0)
+
+#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
+
+#define SLIST_REMOVE_HEAD(head, field) do { \
+ (head)->slh_first = (head)->slh_first->field.sle_next; \
+} while (0)
+
+#define SLIST_REMOVE(head, elm, type, field) do { \
+ if ((head)->slh_first == (elm)) { \
+ SLIST_REMOVE_HEAD((head), field); \
+ } \
+ else { \
+ struct type *curelm = (head)->slh_first; \
+ while( curelm->field.sle_next != (elm) ) \
+ curelm = curelm->field.sle_next; \
+ curelm->field.sle_next = \
+ curelm->field.sle_next->field.sle_next; \
+ } \
+} while (0)
+
+/*
+ * Singly-linked Tail queue definitions.
+ */
+#define STAILQ_HEAD(name, type) \
+struct name { \
+ struct type *stqh_first;/* first element */ \
+ struct type **stqh_last;/* addr of last next element */ \
+}
+
+#define STAILQ_HEAD_INITIALIZER(head) \
+ { NULL, &(head).stqh_first }
+
+#define STAILQ_ENTRY(type) \
+struct { \
+ struct type *stqe_next; /* next element */ \
+}
+
+/*
+ * Singly-linked Tail queue functions.
+ */
+#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL)
+
+#define STAILQ_INIT(head) do { \
+ (head)->stqh_first = NULL; \
+ (head)->stqh_last = &(head)->stqh_first; \
+} while (0)
+
+#define STAILQ_FIRST(head) ((head)->stqh_first)
+#define STAILQ_LAST(head) (*(head)->stqh_last)
+
+#define STAILQ_FOREACH(var, head, field) \
+ for((var) = (head)->stqh_first; (var); (var) = (var)->field.stqe_next)
+
+#define STAILQ_INSERT_HEAD(head, elm, field) do { \
+ if (((elm)->field.stqe_next = (head)->stqh_first) == NULL) \
+ (head)->stqh_last = &(elm)->field.stqe_next; \
+ (head)->stqh_first = (elm); \
+} while (0)
+
+#define STAILQ_INSERT_TAIL(head, elm, field) do { \
+ (elm)->field.stqe_next = NULL; \
+ *(head)->stqh_last = (elm); \
+ (head)->stqh_last = &(elm)->field.stqe_next; \
+} while (0)
+
+#define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \
+ if (((elm)->field.stqe_next = (tqelm)->field.stqe_next) == NULL)\
+ (head)->stqh_last = &(elm)->field.stqe_next; \
+ (tqelm)->field.stqe_next = (elm); \
+} while (0)
+
+#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
+
+#define STAILQ_REMOVE_HEAD(head, field) do { \
+ if (((head)->stqh_first = \
+ (head)->stqh_first->field.stqe_next) == NULL) \
+ (head)->stqh_last = &(head)->stqh_first; \
+} while (0)
+
+#define STAILQ_REMOVE_HEAD_UNTIL(head, elm, field) do { \
+ if (((head)->stqh_first = (elm)->field.stqe_next) == NULL) \
+ (head)->stqh_last = &(head)->stqh_first; \
+} while (0)
+
+#define STAILQ_REMOVE(head, elm, type, field) do { \
+ if ((head)->stqh_first == (elm)) { \
+ STAILQ_REMOVE_HEAD(head, field); \
+ } \
+ else { \
+ struct type *curelm = (head)->stqh_first; \
+ while( curelm->field.stqe_next != (elm) ) \
+ curelm = curelm->field.stqe_next; \
+ if((curelm->field.stqe_next = \
+ curelm->field.stqe_next->field.stqe_next) == NULL) \
+ (head)->stqh_last = &(curelm)->field.stqe_next; \
+ } \
+} while (0)
+
+/*
+ * List definitions.
+ */
+#define LIST_HEAD(name, type) \
+struct name { \
+ struct type *lh_first; /* first element */ \
+}
+
+#define LIST_HEAD_INITIALIZER(head) \
+ { NULL }
+
+#define LIST_ENTRY(type) \
+struct { \
+ struct type *le_next; /* next element */ \
+ struct type **le_prev; /* address of previous next element */ \
+}
+
+/*
+ * List functions.
+ */
+
+#define LIST_EMPTY(head) ((head)->lh_first == NULL)
+
+#define LIST_FIRST(head) ((head)->lh_first)
+
+#define LIST_FOREACH(var, head, field) \
+ for((var) = (head)->lh_first; (var); (var) = (var)->field.le_next)
+
+#define LIST_INIT(head) do { \
+ (head)->lh_first = NULL; \
+} while (0)
+
+#define LIST_INSERT_AFTER(listelm, elm, field) do { \
+ if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
+ (listelm)->field.le_next->field.le_prev = \
+ &(elm)->field.le_next; \
+ (listelm)->field.le_next = (elm); \
+ (elm)->field.le_prev = &(listelm)->field.le_next; \
+} while (0)
+
+#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
+ (elm)->field.le_prev = (listelm)->field.le_prev; \
+ (elm)->field.le_next = (listelm); \
+ *(listelm)->field.le_prev = (elm); \
+ (listelm)->field.le_prev = &(elm)->field.le_next; \
+} while (0)
+
+#define LIST_INSERT_HEAD(head, elm, field) do { \
+ if (((elm)->field.le_next = (head)->lh_first) != NULL) \
+ (head)->lh_first->field.le_prev = &(elm)->field.le_next;\
+ (head)->lh_first = (elm); \
+ (elm)->field.le_prev = &(head)->lh_first; \
+} while (0)
+
+#define LIST_NEXT(elm, field) ((elm)->field.le_next)
+
+#define LIST_REMOVE(elm, field) do { \
+ if ((elm)->field.le_next != NULL) \
+ (elm)->field.le_next->field.le_prev = \
+ (elm)->field.le_prev; \
+ *(elm)->field.le_prev = (elm)->field.le_next; \
+} while (0)
+
+/*
+ * Tail queue definitions.
+ */
+#define TAILQ_HEAD(name, type) \
+struct name { \
+ struct type *tqh_first; /* first element */ \
+ struct type **tqh_last; /* addr of last next element */ \
+}
+
+#define TAILQ_HEAD_INITIALIZER(head) \
+ { NULL, &(head).tqh_first }
+
+#define TAILQ_ENTRY(type) \
+struct { \
+ struct type *tqe_next; /* next element */ \
+ struct type **tqe_prev; /* address of previous next element */ \
+}
+
+/*
+ * Tail queue functions.
+ */
+#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL)
+
+#define TAILQ_FOREACH(var, head, field) \
+ for (var = TAILQ_FIRST(head); var; var = TAILQ_NEXT(var, field))
+
+#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
+ for ((var) = TAILQ_LAST((head), headname); \
+ (var); \
+ (var) = TAILQ_PREV((var), headname, field))
+
+#define TAILQ_FIRST(head) ((head)->tqh_first)
+
+#define TAILQ_LAST(head, headname) \
+ (*(((struct headname *)((head)->tqh_last))->tqh_last))
+
+#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
+
+#define TAILQ_PREV(elm, headname, field) \
+ (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
+
+#define TAILQ_INIT(head) do { \
+ (head)->tqh_first = NULL; \
+ (head)->tqh_last = &(head)->tqh_first; \
+} while (0)
+
+#define TAILQ_INSERT_HEAD(head, elm, field) do { \
+ if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
+ (head)->tqh_first->field.tqe_prev = \
+ &(elm)->field.tqe_next; \
+ else \
+ (head)->tqh_last = &(elm)->field.tqe_next; \
+ (head)->tqh_first = (elm); \
+ (elm)->field.tqe_prev = &(head)->tqh_first; \
+} while (0)
+
+#define TAILQ_INSERT_TAIL(head, elm, field) do { \
+ (elm)->field.tqe_next = NULL; \
+ (elm)->field.tqe_prev = (head)->tqh_last; \
+ *(head)->tqh_last = (elm); \
+ (head)->tqh_last = &(elm)->field.tqe_next; \
+} while (0)
+
+#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
+ if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
+ (elm)->field.tqe_next->field.tqe_prev = \
+ &(elm)->field.tqe_next; \
+ else \
+ (head)->tqh_last = &(elm)->field.tqe_next; \
+ (listelm)->field.tqe_next = (elm); \
+ (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
+} while (0)
+
+#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
+ (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
+ (elm)->field.tqe_next = (listelm); \
+ *(listelm)->field.tqe_prev = (elm); \
+ (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
+} while (0)
+
+#define TAILQ_REMOVE(head, elm, field) do { \
+ if (((elm)->field.tqe_next) != NULL) \
+ (elm)->field.tqe_next->field.tqe_prev = \
+ (elm)->field.tqe_prev; \
+ else \
+ (head)->tqh_last = (elm)->field.tqe_prev; \
+ *(elm)->field.tqe_prev = (elm)->field.tqe_next; \
+} while (0)
+
+/*
+ * Circular queue definitions.
+ */
+#define CIRCLEQ_HEAD(name, type) \
+struct name { \
+ struct type *cqh_first; /* first element */ \
+ struct type *cqh_last; /* last element */ \
+}
+
+#define CIRCLEQ_ENTRY(type) \
+struct { \
+ struct type *cqe_next; /* next element */ \
+ struct type *cqe_prev; /* previous element */ \
+}
+
+/*
+ * Circular queue functions.
+ */
+#define CIRCLEQ_EMPTY(head) ((head)->cqh_first == (void *)(head))
+
+#define CIRCLEQ_FIRST(head) ((head)->cqh_first)
+
+#define CIRCLEQ_FOREACH(var, head, field) \
+ for((var) = (head)->cqh_first; \
+ (var) != (void *)(head); \
+ (var) = (var)->field.cqe_next)
+
+#define CIRCLEQ_FOREACH_REVERSE(var, head, field) \
+ for((var) = (head)->cqh_last; \
+ (var) != (void *)(head); \
+ (var) = (var)->field.cqe_prev)
+
+#define CIRCLEQ_INIT(head) do { \
+ (head)->cqh_first = (void *)(head); \
+ (head)->cqh_last = (void *)(head); \
+} while (0)
+
+#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
+ (elm)->field.cqe_next = (listelm)->field.cqe_next; \
+ (elm)->field.cqe_prev = (listelm); \
+ if ((listelm)->field.cqe_next == (void *)(head)) \
+ (head)->cqh_last = (elm); \
+ else \
+ (listelm)->field.cqe_next->field.cqe_prev = (elm); \
+ (listelm)->field.cqe_next = (elm); \
+} while (0)
+
+#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \
+ (elm)->field.cqe_next = (listelm); \
+ (elm)->field.cqe_prev = (listelm)->field.cqe_prev; \
+ if ((listelm)->field.cqe_prev == (void *)(head)) \
+ (head)->cqh_first = (elm); \
+ else \
+ (listelm)->field.cqe_prev->field.cqe_next = (elm); \
+ (listelm)->field.cqe_prev = (elm); \
+} while (0)
+
+#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \
+ (elm)->field.cqe_next = (head)->cqh_first; \
+ (elm)->field.cqe_prev = (void *)(head); \
+ if ((head)->cqh_last == (void *)(head)) \
+ (head)->cqh_last = (elm); \
+ else \
+ (head)->cqh_first->field.cqe_prev = (elm); \
+ (head)->cqh_first = (elm); \
+} while (0)
+
+#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \
+ (elm)->field.cqe_next = (void *)(head); \
+ (elm)->field.cqe_prev = (head)->cqh_last; \
+ if ((head)->cqh_first == (void *)(head)) \
+ (head)->cqh_first = (elm); \
+ else \
+ (head)->cqh_last->field.cqe_next = (elm); \
+ (head)->cqh_last = (elm); \
+} while (0)
+
+#define CIRCLEQ_LAST(head) ((head)->cqh_last)
+
+#define CIRCLEQ_NEXT(elm,field) ((elm)->field.cqe_next)
+
+#define CIRCLEQ_PREV(elm,field) ((elm)->field.cqe_prev)
+
+#define CIRCLEQ_REMOVE(head, elm, field) do { \
+ if ((elm)->field.cqe_next == (void *)(head)) \
+ (head)->cqh_last = (elm)->field.cqe_prev; \
+ else \
+ (elm)->field.cqe_next->field.cqe_prev = \
+ (elm)->field.cqe_prev; \
+ if ((elm)->field.cqe_prev == (void *)(head)) \
+ (head)->cqh_first = (elm)->field.cqe_next; \
+ else \
+ (elm)->field.cqe_prev->field.cqe_next = \
+ (elm)->field.cqe_next; \
+} while (0)
+
+#ifdef KERNEL
+
+/*
+ * XXX insque() and remque() are an old way of handling certain queues.
+ * They bogusly assumes that all queue heads look alike.
+ */
+
+struct quehead {
+ struct quehead *qh_link;
+ struct quehead *qh_rlink;
+};
+
+#ifdef __GNUC__
+
+static __inline void
+insque(void *a, void *b)
+{
+ struct quehead *element = a, *head = b;
+
+ element->qh_link = head->qh_link;
+ element->qh_rlink = head;
+ head->qh_link = element;
+ element->qh_link->qh_rlink = element;
+}
+
+static __inline void
+remque(void *a)
+{
+ struct quehead *element = a;
+
+ element->qh_link->qh_rlink = element->qh_rlink;
+ element->qh_rlink->qh_link = element->qh_link;
+ element->qh_rlink = 0;
+}
+
+#else /* !__GNUC__ */
+
+void insque __P((void *a, void *b));
+void remque __P((void *a));
+
+#endif /* __GNUC__ */
+
+#endif /* KERNEL */
+
+#endif /* !_SYS_QUEUE_H_ */
+