summaryrefslogtreecommitdiff
path: root/include/asterisk
diff options
context:
space:
mode:
Diffstat (limited to 'include/asterisk')
-rw-r--r--include/asterisk/_private.h1
-rw-r--r--include/asterisk/alertpipe.h160
-rw-r--r--include/asterisk/app.h31
-rw-r--r--include/asterisk/ari.h10
-rw-r--r--include/asterisk/astmm.h15
-rw-r--r--include/asterisk/astobj2.h21
-rw-r--r--include/asterisk/autochan.h20
-rw-r--r--include/asterisk/autoconfig.h.in68
-rw-r--r--include/asterisk/bridge.h25
-rw-r--r--include/asterisk/bridge_after.h2
-rw-r--r--include/asterisk/bridge_channel.h34
-rw-r--r--include/asterisk/bridge_channel_internal.h11
-rw-r--r--include/asterisk/bridge_technology.h39
-rw-r--r--include/asterisk/cdr.h44
-rw-r--r--include/asterisk/cel.h23
-rw-r--r--include/asterisk/channel.h273
-rw-r--r--include/asterisk/channel_internal.h2
-rw-r--r--include/asterisk/codec.h13
-rw-r--r--include/asterisk/compat.h20
-rw-r--r--include/asterisk/config.h11
-rw-r--r--include/asterisk/config_options.h24
-rw-r--r--include/asterisk/conversions.h62
-rw-r--r--include/asterisk/core_local.h37
-rw-r--r--include/asterisk/data.h828
-rw-r--r--include/asterisk/features_config.h15
-rw-r--r--include/asterisk/format.h15
-rw-r--r--include/asterisk/format_cache.h10
-rw-r--r--include/asterisk/frame.h7
-rw-r--r--include/asterisk/indications.h9
-rw-r--r--include/asterisk/io.h24
-rw-r--r--include/asterisk/lock.h9
-rw-r--r--include/asterisk/logger.h27
-rw-r--r--include/asterisk/manager.h2
-rw-r--r--include/asterisk/module.h85
-rw-r--r--include/asterisk/netsock2.h16
-rw-r--r--include/asterisk/network.h5
-rw-r--r--include/asterisk/options.h6
-rw-r--r--include/asterisk/res_hep.h2
-rw-r--r--include/asterisk/res_pjsip.h390
-rw-r--r--include/asterisk/res_pjsip_presence_xml.h3
-rw-r--r--include/asterisk/res_pjsip_session.h291
-rw-r--r--include/asterisk/rtp_engine.h119
-rw-r--r--include/asterisk/sdp.h703
-rw-r--r--include/asterisk/sdp_options.h731
-rw-r--r--include/asterisk/sdp_priv.h130
-rw-r--r--include/asterisk/sdp_state.h297
-rw-r--r--include/asterisk/sdp_translator.h13
-rw-r--r--include/asterisk/smoother.h1
-rw-r--r--include/asterisk/sorcery.h11
-rw-r--r--include/asterisk/stasis_app.h33
-rw-r--r--include/asterisk/stasis_channels.h1
-rw-r--r--include/asterisk/stasis_endpoints.h1
-rw-r--r--include/asterisk/stasis_system.h1
-rw-r--r--include/asterisk/stream.h203
-rw-r--r--include/asterisk/strings.h64
-rw-r--r--include/asterisk/test.h8
-rw-r--r--include/asterisk/utils.h8
-rw-r--r--include/asterisk/vector.h103
-rw-r--r--include/asterisk/xml.h5
59 files changed, 3734 insertions, 1388 deletions
diff --git a/include/asterisk/_private.h b/include/asterisk/_private.h
index b3c2b2002..e989b16fd 100644
--- a/include/asterisk/_private.h
+++ b/include/asterisk/_private.h
@@ -44,7 +44,6 @@ int ast_named_locks_init(void); /*!< Provided by named_locks.c */
int ast_file_init(void); /*!< Provided by file.c */
int ast_features_init(void); /*!< Provided by features.c */
void ast_autoservice_init(void); /*!< Provided by autoservice.c */
-int ast_data_init(void); /*!< Provided by data.c */
int ast_http_init(void); /*!< Provided by http.c */
int ast_http_reload(void); /*!< Provided by http.c */
int ast_tps_init(void); /*!< Provided by taskprocessor.c */
diff --git a/include/asterisk/alertpipe.h b/include/asterisk/alertpipe.h
new file mode 100644
index 000000000..09c335829
--- /dev/null
+++ b/include/asterisk/alertpipe.h
@@ -0,0 +1,160 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2017, Sean Bright
+ *
+ * Sean Bright <sean.bright@gmail.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_ALERTPIPE_H
+#define ASTERISK_ALERTPIPE_H
+
+#include "asterisk/utils.h"
+
+typedef enum {
+ AST_ALERT_READ_SUCCESS = 0,
+ AST_ALERT_NOT_READABLE,
+ AST_ALERT_READ_FAIL,
+ AST_ALERT_READ_FATAL,
+} ast_alert_status_t;
+
+/*!
+ * \brief Initialize an alert pipe
+ * \since 13.16.0
+ *
+ * \param p a two-element array to hold the alert pipe's file descriptors
+ *
+ * \return non-zero if a failure occurred, zero otherwise.
+ */
+int ast_alertpipe_init(int alert_pipe[2]);
+
+/*!
+ * \brief Close an alert pipe
+ * \since 13.16.0
+ *
+ * \param p a two-element containing the alert pipe's file descriptors
+ */
+void ast_alertpipe_close(int alert_pipe[2]);
+
+/*!
+ * \brief Read an event from an alert pipe
+ * \since 13.16.0
+ *
+ * \param p a two-element array containing the alert pipe's file descriptors
+ *
+ * \retval AST_ALERT_READ_SUCCESS on success
+ * \retval AST_ALERT_NOT_READABLE if the alert pipe is not readable
+ * \retval AST_ALERT_READ_FATAL if the alert pipe's file descriptors are in
+ * blocking mode, or a read error occurs.
+ */
+ast_alert_status_t ast_alertpipe_read(int alert_pipe[2]);
+
+/*!
+ * \brief Write an event to an alert pipe
+ * \since 13.16.0
+ *
+ * \param p a two-element array containing the alert pipe's file descriptors
+ *
+ * \retval 0 Success
+ * \retval 1 Failure
+ */
+ssize_t ast_alertpipe_write(int alert_pipe[2]);
+
+/*!
+ * \brief Consume all alerts written to the alert pipe
+ * \since 13.16.0
+ *
+ * \param p a two-element array containing the alert pipe's file descriptors
+ *
+ * \retval AST_ALERT_READ_SUCCESS on success
+ * \retval AST_ALERT_NOT_READABLE if the alert pipe is not readable
+ * \retval AST_ALERT_READ_FATAL if the alert pipe's file descriptors are in
+ * blocking mode, or a read error occurs.
+ */
+ast_alert_status_t ast_alertpipe_flush(int alert_pipe[2]);
+
+/*!
+ * \brief Sets the alert pipe file descriptors to default values
+ * \since 13.16.0
+ *
+ * \param p a two-element array containing the alert pipe's file descriptors
+ */
+AST_INLINE_API(
+void ast_alertpipe_clear(int alert_pipe[2]),
+{
+ alert_pipe[0] = alert_pipe[1] = -1;
+}
+)
+
+/*!
+ * \brief Determine if the alert pipe is readable
+ * \since 13.16.0
+ *
+ * \param p a two-element array containing the alert pipe's file descriptors
+ *
+ * \return non-zero if the alert pipe is readable, zero otherwise.
+ */
+AST_INLINE_API(
+int attribute_pure ast_alertpipe_readable(int alert_pipe[2]),
+{
+ return alert_pipe[0] > -1;
+}
+)
+
+/*!
+ * \brief Determine if the alert pipe is writable
+ * \since 13.16.0
+ *
+ * \param p a two-element array containing the alert pipe's file descriptors
+ *
+ * \return non-zero if the alert pipe is writable, zero otherwise.
+ */
+AST_INLINE_API(
+int attribute_pure ast_alertpipe_writable(int alert_pipe[2]),
+{
+ return alert_pipe[1] > -1;
+}
+)
+
+/*!
+ * \brief Get the alert pipe's read file descriptor
+ * \since 13.16.0
+ *
+ * \param p a two-element array containing the alert pipe's file descriptors
+ *
+ * \return -1 if the file descriptor is not initialized, a non-negative value
+ * otherwise.
+ */
+AST_INLINE_API(
+int attribute_pure ast_alertpipe_readfd(int alert_pipe[2]),
+{
+ return alert_pipe[0];
+}
+)
+
+/*!
+ * \brief Swap the file descriptors from two alert pipes
+ * \since 13.16.0
+ *
+ * \param p1 a two-element array containing an alert pipe's file descriptors
+ * \param p2 a two-element array containing an alert pipe's file descriptors
+ */
+AST_INLINE_API(
+void ast_alertpipe_swap(int alert_pipe_1[2], int alert_pipe_2[2]),
+{
+ SWAP(alert_pipe_1[0], alert_pipe_2[0]);
+ SWAP(alert_pipe_1[1], alert_pipe_2[1]);
+}
+)
+
+#endif /* ASTERISK_ALERTPIPE_H */
diff --git a/include/asterisk/app.h b/include/asterisk/app.h
index d86b63338..0505a6b98 100644
--- a/include/asterisk/app.h
+++ b/include/asterisk/app.h
@@ -871,9 +871,34 @@ int ast_vm_test_destroy_user(const char *context, const char *mailbox);
int ast_vm_test_create_user(const char *context, const char *mailbox);
#endif
-/*! \brief Safely spawn an external program while closing file descriptors
- \note This replaces the \b system call in all Asterisk modules
-*/
+/*!
+ * \brief Safely spawn an external program while closing file descriptors
+ *
+ * \note This replaces the \b execvp call in all Asterisk modules
+ *
+ * \param dualfork Non-zero to simulate running the program in the
+ * background by forking twice. The option provides similar
+ * functionality to the '&' in the OS shell command "cmd &". The
+ * option allows Asterisk to run a reaper loop to watch the first fork
+ * which immediately exits after spaning the second fork. The actual
+ * program is run in the second fork.
+ * \param file execvp(file, argv) file parameter
+ * \param argv execvp(file, argv) argv parameter
+ */
+int ast_safe_execvp(int dualfork, const char *file, char *const argv[]);
+
+/*!
+ * \brief Safely spawn an OS shell command while closing file descriptors
+ *
+ * \note This replaces the \b system call in all Asterisk modules
+ *
+ * \param s - OS shell command string to execute.
+ *
+ * \warning Command injection can happen using this call if the passed
+ * in string is created using untrusted data from an external source.
+ * It is best not to use untrusted data. However, the caller could
+ * filter out dangerous characters to avoid command injection.
+ */
int ast_safe_system(const char *s);
/*!
diff --git a/include/asterisk/ari.h b/include/asterisk/ari.h
index 865b4b00c..f83d5963f 100644
--- a/include/asterisk/ari.h
+++ b/include/asterisk/ari.h
@@ -268,4 +268,14 @@ void ast_ari_response_created(struct ast_ari_response *response,
*/
void ast_ari_response_alloc_failed(struct ast_ari_response *response);
+/*! \brief Determines whether the res_ari module is loaded */
+#define CHECK_ARI_MODULE_LOADED() \
+ do { \
+ if (!ast_module_check("res_ari.so") \
+ || !ast_ari_oom_json()) { \
+ return AST_MODULE_LOAD_DECLINE; \
+ } \
+ } while(0)
+
+
#endif /* _ASTERISK_ARI_H */
diff --git a/include/asterisk/astmm.h b/include/asterisk/astmm.h
index e129dc034..06300c861 100644
--- a/include/asterisk/astmm.h
+++ b/include/asterisk/astmm.h
@@ -30,21 +30,10 @@ extern "C" {
#ifndef _ASTERISK_ASTMM_H
#define _ASTERISK_ASTMM_H
-/* IWYU pragma: private, include "asterisk/utils.h" */
-
-#ifndef STANDALONE
+/* IWYU pragma: private, include "asterisk.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>
-
void *ast_std_malloc(size_t size);
void *ast_std_calloc(size_t nmemb, size_t size);
void *ast_std_realloc(void *ptr, size_t size);
@@ -179,8 +168,6 @@ void __ast_mm_init_phase_2(void);
#define ast_free(a) \
__ast_free(a,__FILE__, __LINE__, __PRETTY_FUNCTION__)
-#endif /* !STANDALONE */
-
#else
#error "NEVER INCLUDE astmm.h DIRECTLY!!"
#endif /* _ASTERISK_ASTMM_H */
diff --git a/include/asterisk/astobj2.h b/include/asterisk/astobj2.h
index 28ae73e87..a18f099c0 100644
--- a/include/asterisk/astobj2.h
+++ b/include/asterisk/astobj2.h
@@ -671,6 +671,10 @@ int ao2_weakproxy_subscribe(void *weakproxy, ao2_weakproxy_notification_cb cb, v
* of the cb / data pair. If it was subscribed multiple times it must be
* unsubscribed as many times. The OBJ_MULTIPLE flag can be used to remove
* matching subscriptions.
+ *
+ * \note When it's time to run callbacks they are copied to a temporary list so the
+ * weakproxy can be unlocked before running. That means it's possible for
+ * this function to find nothing before the callback is run in another thread.
*/
int ao2_weakproxy_unsubscribe(void *weakproxy, ao2_weakproxy_notification_cb cb, void *data, int flags);
@@ -854,11 +858,9 @@ struct ao2_global_obj {
* \return Nothing
*/
#define ao2_t_global_obj_release(holder, tag) \
- __ao2_global_obj_release(&holder, (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__, #holder)
+ __ao2_global_obj_replace_unref(&holder, NULL, (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__, #holder)
#define ao2_global_obj_release(holder) \
- __ao2_global_obj_release(&holder, "", __FILE__, __LINE__, __PRETTY_FUNCTION__, #holder)
-
-void __ao2_global_obj_release(struct ao2_global_obj *holder, const char *tag, const char *file, int line, const char *func, const char *name);
+ __ao2_global_obj_replace_unref(&holder, NULL, "", __FILE__, __LINE__, __PRETTY_FUNCTION__, #holder)
/*!
* \brief Replace an ao2 object in the global holder.
@@ -1773,6 +1775,17 @@ void *__ao2_callback_data(struct ao2_container *c, enum search_flags flags,
void *__ao2_find(struct ao2_container *c, const void *arg, enum search_flags flags,
const char *tag, const char *file, int line, const char *func);
+/*!
+ * \brief Perform an ao2_find on a container with ao2_weakproxy objects, returning the real object.
+ *
+ * \note Only OBJ_SEARCH_* and OBJ_NOLOCK flags are supported by this function.
+ * \see ao2_callback for description of arguments.
+ */
+#define ao2_weakproxy_find(c, arg, flags, tag) \
+ __ao2_weakproxy_find(c, arg, flags, tag, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+void *__ao2_weakproxy_find(struct ao2_container *c, const void *arg, enum search_flags flags,
+ const char *tag, const char *file, int line, const char *func);
+
/*! \brief
*
*
diff --git a/include/asterisk/autochan.h b/include/asterisk/autochan.h
index 319c203ab..128377b57 100644
--- a/include/asterisk/autochan.h
+++ b/include/asterisk/autochan.h
@@ -32,6 +32,7 @@
struct ast_autochan {
struct ast_channel *chan;
AST_LIST_ENTRY(ast_autochan) list;
+ ast_mutex_t lock;
};
/*!
@@ -61,19 +62,24 @@ struct ast_autochan {
* ast_autochan_channel_lock and ast_autochan_channel_unlock. An attempt to lock
* the autochan->chan directly may result in it being changed after you've
* retrieved the value of chan, but before you've had a chance to lock it.
- * First when chan is locked, the autochan structure is guaranteed to keep the
+ * While chan is locked, the autochan structure is guaranteed to keep the
* same channel.
*/
+/*!
+ * \brief Lock the autochan's channel lock.
+ *
+ * \note We must do deadlock avoidance because the channel lock is
+ * superior to the autochan lock in locking order.
+ */
#define ast_autochan_channel_lock(autochan) \
do { \
- struct ast_channel *autochan_chan = autochan->chan; \
- ast_channel_lock(autochan_chan); \
- if (autochan->chan == autochan_chan) { \
- break; \
+ ast_mutex_lock(&(autochan)->lock); \
+ while (ast_channel_trylock((autochan)->chan)) { \
+ DEADLOCK_AVOIDANCE(&(autochan)->lock); \
} \
- ast_channel_unlock(autochan_chan); \
- } while (1)
+ ast_mutex_unlock(&(autochan)->lock); \
+ } while (0)
#define ast_autochan_channel_unlock(autochan) \
ast_channel_unlock(autochan->chan)
diff --git a/include/asterisk/autoconfig.h.in b/include/asterisk/autoconfig.h.in
index c7a190892..4700d4092 100644
--- a/include/asterisk/autoconfig.h.in
+++ b/include/asterisk/autoconfig.h.in
@@ -9,6 +9,9 @@
/* Define to 1 if internal poll should be used. */
#undef AST_POLL_COMPAT
+/* Define to enable XML documentation. */
+#undef AST_XML_DOCS
+
/* Define to 1 if your system's implementation of mutexes supports comparison
of a mutex to its initializer. */
#undef CAN_COMPARE_MUTEX_TO_INIT_VALUE
@@ -62,6 +65,9 @@
/* Define to 1 if you have the `asprintf' function. */
#undef HAVE_ASPRINTF
+/* Define to 1 if you have the <assert.h> header file. */
+#undef HAVE_ASSERT_H
+
/* Define to 1 if you have the `atan' function. */
#undef HAVE_ATAN
@@ -173,6 +179,9 @@
/* Define to 1 if you have the 'crypt_r' function. */
#undef HAVE_CRYPT_R
+/* Define to 1 if you have the <ctype.h> header file. */
+#undef HAVE_CTYPE_H
+
/* Define to 1 if you have a functional curl library. */
#undef HAVE_CURL
@@ -201,6 +210,9 @@
/* Define to 1 if your system has the dladdr() GNU extension */
#undef HAVE_DLADDR
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
#undef HAVE_DOPRNT
@@ -213,9 +225,16 @@
/* Define to 1 if you have the `endpwent' function. */
#undef HAVE_ENDPWENT
+/* Define to 1 if you have the <errno.h> header file. */
+#undef HAVE_ERRNO_H
+
/* Define to 1 if you have the `euidaccess' function. */
#undef HAVE_EUIDACCESS
+/* Define to 1 if your system supports eventfd and the EFD_NONBLOCK and
+ EFD_SEMAPHORE flags. */
+#undef HAVE_EVENTFD
+
/* Define to 1 if you have the `exp' function. */
#undef HAVE_EXP
@@ -246,6 +265,9 @@
/* Define to 1 if you have the LIBFFTW3 library. */
#undef HAVE_FFTW3
+/* Define to 1 if you have the <float.h> header file. */
+#undef HAVE_FLOAT_H
+
/* Define to 1 if you have the `floor' function. */
#undef HAVE_FLOOR
@@ -315,6 +337,9 @@
/* Define if your system has the GMIME libraries. */
#undef HAVE_GMIME
+/* Define to 1 if you have the <grp.h> header file. */
+#undef HAVE_GRP_H
+
/* Define to indicate the GSM library */
#undef HAVE_GSM
@@ -464,6 +489,9 @@
/* Define to 1 if you have the <malloc.h> header file. */
#undef HAVE_MALLOC_H
+/* Define to 1 if you have the <math.h> header file. */
+#undef HAVE_MATH_H
+
/* Define to 1 if you have the `memchr' function. */
#undef HAVE_MEMCHR
@@ -563,6 +591,9 @@
/* Define to 1 if you have the Opus library. */
#undef HAVE_OPUS
+/* Define to 1 if you have the Opusfile library. */
+#undef HAVE_OPUSFILE
+
/* Define this to indicate the ${OSPTK_DESCRIP} library */
#undef HAVE_OSPTK
@@ -621,6 +652,10 @@
/* Define if your system has the PJSIP_TLS_TRANSPORT_PROTO headers. */
#undef HAVE_PJSIP_TLS_TRANSPORT_PROTO
+/* Define to 1 if PJPROJECT has the pjsip_tsx_layer_find_tsx2 support feature.
+ */
+#undef HAVE_PJSIP_TSX_LAYER_FIND_TSX2
+
/* Define to 1 if PJPROJECT has the pj_ssl_cert_load_from_files2 support
feature. */
#undef HAVE_PJ_SSL_CERT_LOAD_FROM_FILES2
@@ -755,6 +790,9 @@
/* Define to 1 if you have the `putenv' function. */
#undef HAVE_PUTENV
+/* Define to 1 if you have the <pwd.h> header file. */
+#undef HAVE_PWD_H
+
/* Define if your system has the PWLib libraries. */
#undef HAVE_PWLIB
@@ -767,6 +805,9 @@
/* Define to 1 if you have the `regcomp' function. */
#undef HAVE_REGCOMP
+/* Define to 1 if you have the <regex.h> header file. */
+#undef HAVE_REGEX_H
+
/* Define to 1 if you have the `remainder' function. */
#undef HAVE_REMAINDER
@@ -776,6 +817,9 @@
/* Define to 1 if you have the LIBRESAMPLE library. */
#undef HAVE_RESAMPLE
+/* Define to 1 if you have the <resolv.h> header file. */
+#undef HAVE_RESOLV_H
+
/* Define to 1 if your system has the close resolver function. */
#undef HAVE_RES_CLOSE
@@ -812,6 +856,9 @@
/* Define to 1 if your system has /sbin/launchd. */
#undef HAVE_SBIN_LAUNCHD
+/* Define to 1 if you have the <sched.h> header file. */
+#undef HAVE_SCHED_H
+
/* Define if your system has the SDL libraries. */
#undef HAVE_SDL
@@ -879,6 +926,9 @@
/* Define to 1 if SRTP has the SRTP Library Shutdown Function feature. */
#undef HAVE_SRTP_SHUTDOWN
+/* Define to the version of the srtp library. */
+#undef HAVE_SRTP_VERSION
+
/* Define to 1 if you have the ISDN SS7 library. */
#undef HAVE_SS7
@@ -892,6 +942,9 @@
zero-length file name argument. */
#undef HAVE_STAT_EMPTY_STRING_BUG
+/* Define to 1 if you have the <stdarg.h> header file. */
+#undef HAVE_STDARG_H
+
/* Define to 1 if stdbool.h conforms to C99. */
#undef HAVE_STDBOOL_H
@@ -901,6 +954,9 @@
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
+/* Define to 1 if you have the <stdio.h> header file. */
+#undef HAVE_STDIO_H
+
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
@@ -1069,9 +1125,6 @@
/* 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
@@ -1082,6 +1135,9 @@
/* Define to 1 if your system has working sys/poll.h */
#undef HAVE_SYS_POLL_H
+/* Define to 1 if you have the <sys/resource.h> header file. */
+#undef HAVE_SYS_RESOURCE_H
+
/* Define to 1 if you have the <sys/select.h> header file. */
#undef HAVE_SYS_SELECT_H
@@ -1100,6 +1156,9 @@
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
+/* Define to 1 if you have the <sys/un.h> header file. */
+#undef HAVE_SYS_UN_H
+
/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
#undef HAVE_SYS_WAIT_H
@@ -1121,6 +1180,9 @@
/* Define to 1 if your system defines timersub. */
#undef HAVE_TIMERSUB
+/* Define to 1 if you have the <time.h> header file. */
+#undef HAVE_TIME_H
+
/* Define to 1 if you have the Term Info library. */
#undef HAVE_TINFO
diff --git a/include/asterisk/bridge.h b/include/asterisk/bridge.h
index ffe08da13..8d5c50211 100644
--- a/include/asterisk/bridge.h
+++ b/include/asterisk/bridge.h
@@ -102,6 +102,10 @@ enum ast_bridge_video_mode_type {
/*! A single user's video feed is distributed to all bridge channels, but
* that feed is automatically picked based on who is talking the most. */
AST_BRIDGE_VIDEO_MODE_TALKER_SRC,
+ /*! Operate as a selective forwarding unit. Video from each participant is
+ * cloned to a dedicated stream on a subset of the remaining participants.
+ */
+ AST_BRIDGE_VIDEO_MODE_SFU,
};
/*! \brief This is used for both SINGLE_SRC mode to set what channel
@@ -130,6 +134,7 @@ struct ast_bridge_video_mode {
struct ast_bridge_video_single_src_data single_src_data;
struct ast_bridge_video_talker_src_data talker_src_data;
} mode_data;
+ unsigned int video_update_discard;
};
/*!
@@ -267,6 +272,8 @@ struct ast_bridge_softmix {
unsigned int binaural_active;
};
+AST_LIST_HEAD_NOLOCK(ast_bridge_channels_list, ast_bridge_channel);
+
/*!
* \brief Structure that contains information about a bridge
*/
@@ -284,7 +291,7 @@ struct ast_bridge {
/*! Call ID associated with the bridge */
ast_callid callid;
/*! Linked list of channels participating in the bridge */
- AST_LIST_HEAD_NOLOCK(, ast_bridge_channel) channels;
+ struct ast_bridge_channels_list channels;
/*! Queue of actions to perform on the bridge. */
AST_LIST_HEAD_NOLOCK(, ast_frame) action_queue;
/*! Softmix technology parameters. */
@@ -323,6 +330,9 @@ struct ast_bridge {
/*! Immutable bridge UUID. */
AST_STRING_FIELD(uniqueid);
);
+
+ /*! Type mapping used for media routing */
+ struct ast_vector_int media_types;
};
/*! \brief Bridge base class virtual method table. */
@@ -889,6 +899,19 @@ void ast_bridge_set_single_src_video_mode(struct ast_bridge *bridge, struct ast_
void ast_bridge_set_talker_src_video_mode(struct ast_bridge *bridge);
/*!
+ * \brief Set the bridge to be a selective forwarding unit
+ */
+void ast_bridge_set_sfu_video_mode(struct ast_bridge *bridge);
+
+/*!
+ * \brief Set the amount of time to discard subsequent video updates after a video update has been sent
+ *
+ * \param bridge Bridge to set the minimum video update wait time on
+ * \param video_update_discard Amount of time after sending a video update that others should be discarded
+ */
+void ast_bridge_set_video_update_discard(struct ast_bridge *bridge, unsigned int video_update_discard);
+
+/*!
* \brief Update information about talker energy for talker src video mode.
*/
void ast_bridge_update_talker_src_video_mode(struct ast_bridge *bridge, struct ast_channel *chan, int talker_energy, int is_keyfame);
diff --git a/include/asterisk/bridge_after.h b/include/asterisk/bridge_after.h
index 53f30b9ad..045168571 100644
--- a/include/asterisk/bridge_after.h
+++ b/include/asterisk/bridge_after.h
@@ -45,6 +45,8 @@ enum ast_bridge_after_cb_reason {
AST_BRIDGE_AFTER_CB_REASON_DEPART,
/*! Was explicitly removed by external code. */
AST_BRIDGE_AFTER_CB_REASON_REMOVED,
+ /*! The channel failed to enter the bridge. */
+ AST_BRIDGE_AFTER_CB_REASON_IMPART_FAILED,
};
/*!
diff --git a/include/asterisk/bridge_channel.h b/include/asterisk/bridge_channel.h
index a7971df27..4504d6bcb 100644
--- a/include/asterisk/bridge_channel.h
+++ b/include/asterisk/bridge_channel.h
@@ -145,6 +145,8 @@ struct ast_bridge_channel {
AST_LIST_ENTRY(ast_bridge_channel) entry;
/*! Queue of outgoing frames to the channel. */
AST_LIST_HEAD_NOLOCK(, ast_frame) wr_queue;
+ /*! Queue of deferred frames, queued onto channel when other party joins. */
+ AST_LIST_HEAD_NOLOCK(, ast_frame) deferred_queue;
/*! Pipe to alert thread when frames are put into the wr_queue. */
int alert_pipe[2];
/*!
@@ -183,6 +185,12 @@ struct ast_bridge_channel {
unsigned int padding:30;
};
};
+ struct {
+ /*! An index mapping of where a channel's media needs to be routed */
+ struct ast_vector_int to_bridge;
+ /*! An index mapping of where a bridge's media needs to be routed */
+ struct ast_vector_int to_channel;
+ } stream_map;
};
/*!
@@ -704,6 +712,32 @@ void ast_bridge_channel_feature_digit_add(struct ast_bridge_channel *bridge_chan
*/
void ast_bridge_channel_feature_digit(struct ast_bridge_channel *bridge_channel, int digit);
+/*!
+ * \brief Maps a channel's stream topology to and from the bridge
+ * \since 15.0.0
+ *
+ * \details
+ * When a channel joins a bridge or its associated stream topology is
+ * updated, each stream in the topology needs to be mapped according
+ * to its media type to the bridge. Calling this method creates a
+ * mapping of each stream on the channel indexed to the bridge's
+ * supported media types and vice versa (i.e. bridge's media types
+ * indexed to channel streams).
+ *
+ * The first channel to join the bridge creates the initial order for
+ * the bridge's media types (e.g. a one to one mapping is made).
+ * Subsequently added channels are mapped to that order adding more
+ * media types if/when the newly added channel has more streams and/or
+ * media types specified by the bridge.
+ *
+ * \param bridge_channel Channel to map
+ *
+ * \note The bridge_channel's bridge must be locked prior to calling this function.
+ *
+ * \return Nothing
+ */
+void ast_bridge_channel_stream_map(struct ast_bridge_channel *bridge_channel);
+
#if defined(__cplusplus) || defined(c_plusplus)
}
#endif
diff --git a/include/asterisk/bridge_channel_internal.h b/include/asterisk/bridge_channel_internal.h
index fb8e781e8..ba71e9fc4 100644
--- a/include/asterisk/bridge_channel_internal.h
+++ b/include/asterisk/bridge_channel_internal.h
@@ -98,6 +98,17 @@ void bridge_channel_settle_owed_events(struct ast_bridge *orig_bridge, struct as
/*!
* \internal
+ * \brief Queue any deferred frames on the channel.
+ * \since 13.17.0
+ *
+ * \param bridge_channel Channel that the deferred frames should be pulled from and queued to.
+ *
+ * \return Nothing
+ */
+void bridge_channel_queue_deferred_frames(struct ast_bridge_channel *bridge_channel);
+
+/*!
+ * \internal
* \brief Push the bridge channel into its specified bridge.
* \since 12.0.0
*
diff --git a/include/asterisk/bridge_technology.h b/include/asterisk/bridge_technology.h
index 8df19d9e9..eaea28de5 100644
--- a/include/asterisk/bridge_technology.h
+++ b/include/asterisk/bridge_technology.h
@@ -108,8 +108,13 @@ struct ast_bridge_technology {
*
* \note On entry, bridge is already locked.
*
- * \note The bridge technology must tollerate a failed to join channel
+ * \note The bridge technology must tolerate a failed to join channel
* until it can be kicked from the bridge.
+ *
+ * \note A channel may be in a suspended state already when joining a bridge
+ * technology. The technology must handle this case.
+ *
+ * \note A channel may not be answered when joining a bridge technology.
*/
int (*join)(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel);
/*!
@@ -153,8 +158,40 @@ struct ast_bridge_technology {
* \retval -1 Frame needs to be deferred.
*
* \note On entry, bridge is already locked.
+ *
+ * \note Deferred frames will be automatically queued onto the channel when another
+ * channel joins the bridge.
*/
int (*write)(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_frame *frame);
+ /*!
+ * \brief Callback for when a request has been made to change a stream topology on a channel
+ *
+ * \details
+ * This is called when a bridge receives a request to change the
+ * topology on the channel. A bridge technology should define a
+ * handler for this callback if it needs to update internals or
+ * intercept the request and not pass it on to other channels.
+ * This can be done by returning a nonzero value.
+ *
+ * \retval 0 Frame can pass to the bridge technology.
+ * \retval non-zero Frame intercepted by the bridge technology.
+ *
+ * \note On entry, bridge is already locked.
+ */
+ int (*stream_topology_request_change)(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel);
+ /*!
+ * \brief Callback for when a stream topology changes on the channel
+ *
+ * \details
+ * This is called when a bridge receives an indication that a
+ * topology has been changed on a channel and the new topology has
+ * been mapped to the bridge. A bridge technology should define a
+ * handler for this callback if it needs to update internals due
+ * to a channel's topology changing.
+ *
+ * \note On entry, bridge is already locked.
+ */
+ void (*stream_topology_changed)(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel);
/*! TRUE if the bridge technology is currently suspended. */
unsigned int suspended:1;
/*! Module this bridge technology belongs to. It is used for reference counting bridges using the technology. */
diff --git a/include/asterisk/cdr.h b/include/asterisk/cdr.h
index f752f7f9f..e10da8223 100644
--- a/include/asterisk/cdr.h
+++ b/include/asterisk/cdr.h
@@ -217,19 +217,19 @@
/*! \brief CDR engine settings */
enum ast_cdr_settings {
- CDR_ENABLED = 1 << 0, /*< Enable CDRs */
- CDR_BATCHMODE = 1 << 1, /*< Whether or not we should dispatch CDRs in batches */
- CDR_UNANSWERED = 1 << 2, /*< Log unanswered CDRs */
- CDR_CONGESTION = 1 << 3, /*< Treat congestion as if it were a failed call */
- CDR_END_BEFORE_H_EXTEN = 1 << 4, /*< End the CDR before the 'h' extension runs */
- CDR_INITIATED_SECONDS = 1 << 5, /*< Include microseconds into the billing time */
- CDR_DEBUG = 1 << 6, /*< Enables extra debug statements */
+ CDR_ENABLED = 1 << 0, /*!< Enable CDRs */
+ CDR_BATCHMODE = 1 << 1, /*!< Whether or not we should dispatch CDRs in batches */
+ CDR_UNANSWERED = 1 << 2, /*!< Log unanswered CDRs */
+ CDR_CONGESTION = 1 << 3, /*!< Treat congestion as if it were a failed call */
+ CDR_END_BEFORE_H_EXTEN = 1 << 4, /*!< End the CDR before the 'h' extension runs */
+ CDR_INITIATED_SECONDS = 1 << 5, /*!< Include microseconds into the billing time */
+ CDR_DEBUG = 1 << 6, /*!< Enables extra debug statements */
};
/*! \brief CDR Batch Mode settings */
enum ast_cdr_batch_mode_settings {
- BATCH_MODE_SCHEDULER_ONLY = 1 << 0, /*< Don't spawn a thread to handle the batches - do it on the scheduler */
- BATCH_MODE_SAFE_SHUTDOWN = 1 << 1, /*< During safe shutdown, submit the batched CDRs */
+ BATCH_MODE_SCHEDULER_ONLY = 1 << 0, /*!< Don't spawn a thread to handle the batches - do it on the scheduler */
+ BATCH_MODE_SAFE_SHUTDOWN = 1 << 1, /*!< During safe shutdown, submit the batched CDRs */
};
/*!
@@ -237,14 +237,14 @@ enum ast_cdr_batch_mode_settings {
* state of a CDR object based on these flags.
*/
enum ast_cdr_options {
- AST_CDR_FLAG_KEEP_VARS = (1 << 0), /*< Copy variables during the operation */
- AST_CDR_FLAG_DISABLE = (1 << 1), /*< Disable the current CDR */
- AST_CDR_FLAG_DISABLE_ALL = (3 << 1), /*< Disable the CDR and all future CDRs */
- AST_CDR_FLAG_PARTY_A = (1 << 3), /*< Set the channel as party A */
- AST_CDR_FLAG_FINALIZE = (1 << 4), /*< Finalize the current CDRs */
- AST_CDR_FLAG_SET_ANSWER = (1 << 5), /*< If the channel is answered, set the answer time to now */
- AST_CDR_FLAG_RESET = (1 << 6), /*< If set, set the start and answer time to now */
- AST_CDR_LOCK_APP = (1 << 7), /*< Prevent any further changes to the application field/data field for this CDR */
+ AST_CDR_FLAG_KEEP_VARS = (1 << 0), /*!< Copy variables during the operation */
+ AST_CDR_FLAG_DISABLE = (1 << 1), /*!< Disable the current CDR */
+ AST_CDR_FLAG_DISABLE_ALL = (3 << 1), /*!< Disable the CDR and all future CDRs */
+ AST_CDR_FLAG_PARTY_A = (1 << 3), /*!< Set the channel as party A */
+ AST_CDR_FLAG_FINALIZE = (1 << 4), /*!< Finalize the current CDRs */
+ AST_CDR_FLAG_SET_ANSWER = (1 << 5), /*!< If the channel is answered, set the answer time to now */
+ AST_CDR_FLAG_RESET = (1 << 6), /*!< If set, set the start and answer time to now */
+ AST_CDR_LOCK_APP = (1 << 7), /*!< Prevent any further changes to the application field/data field for this CDR */
};
/*!
@@ -262,11 +262,11 @@ enum ast_cdr_disposition {
/*! \brief The global options available for CDRs */
struct ast_cdr_config {
- struct ast_flags settings; /*< CDR settings */
+ struct ast_flags settings; /*!< CDR settings */
struct batch_settings {
- unsigned int time; /*< Time between batches */
- unsigned int size; /*< Size to trigger a batch */
- struct ast_flags settings; /*< Settings for batches */
+ unsigned int time; /*!< Time between batches */
+ unsigned int size; /*!< Size to trigger a batch */
+ struct ast_flags settings; /*!< Settings for batches */
} batch_settings;
};
@@ -312,7 +312,7 @@ struct ast_cdr {
unsigned int flags;
/*! Unique Channel Identifier */
char uniqueid[AST_MAX_UNIQUEID];
- /* Linked group Identifier */
+ /*! Linked group Identifier */
char linkedid[AST_MAX_UNIQUEID];
/*! User field */
char userfield[AST_MAX_USER_FIELD];
diff --git a/include/asterisk/cel.h b/include/asterisk/cel.h
index 350b4bf9f..c77a3538c 100644
--- a/include/asterisk/cel.h
+++ b/include/asterisk/cel.h
@@ -87,29 +87,6 @@ enum ast_cel_event_type {
*/
unsigned int ast_cel_check_enabled(void);
-/*!
- * \brief Allocate a CEL record
- *
- * \since 1.8
- *
- * \note The CEL record must be destroyed with ast_cel_destroy().
- *
- * \retval non-NULL an allocated ast_cel structure
- * \retval NULL error
- */
-struct ast_cel *ast_cel_alloc(void);
-
-/*!
- * \brief Destroy a CEL record.
- *
- * \param cel the record to destroy
- *
- * \since 1.8
- *
- * \return nothing.
- */
-void ast_cel_destroy(struct ast_cel *cel);
-
/*!
* \brief Get the name of a CEL event type
*
diff --git a/include/asterisk/channel.h b/include/asterisk/channel.h
index 80476a4e0..3dfbe61d9 100644
--- a/include/asterisk/channel.h
+++ b/include/asterisk/channel.h
@@ -123,6 +123,7 @@ References:
#ifndef _ASTERISK_CHANNEL_H
#define _ASTERISK_CHANNEL_H
+#include "asterisk/alertpipe.h"
#include "asterisk/abstract_jb.h"
#include "asterisk/astobj2.h"
#include "asterisk/poll-compat.h"
@@ -173,17 +174,17 @@ extern "C" {
#include "asterisk/linkedlists.h"
#include "asterisk/stringfields.h"
#include "asterisk/datastore.h"
-#include "asterisk/data.h"
+#include "asterisk/format_cap.h"
#include "asterisk/channelstate.h"
#include "asterisk/ccss.h"
#include "asterisk/framehook.h"
#include "asterisk/stasis.h"
-#include "asterisk/json.h"
#include "asterisk/endpoints.h"
#define DATASTORE_INHERIT_FOREVER INT_MAX
-#define AST_MAX_FDS 11
+#define AST_MAX_FDS 11 /*!< original maximum number of file descriptors */
+#define AST_EXTENDED_FDS 12 /*!< the start of extended file descriptor positions */
/*
* We have AST_MAX_FDS file descriptors in a channel.
* Some of them have a fixed use:
@@ -203,6 +204,8 @@ enum ast_bridge_result {
typedef unsigned long long ast_group_t;
+struct ast_stream_topology;
+
/*! \todo Add an explanation of an Asterisk generator
*/
struct ast_generator {
@@ -630,6 +633,26 @@ struct ast_channel_tech {
*/
struct ast_channel *(* const requester)(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *addr, int *cause);
+ /*!
+ * \brief Requester - to set up call data structures (pvt's) with stream topology
+ *
+ * \param type type of channel to request
+ * \param topology Stream topology for requested channel
+ * \param assignedid Unique ID string to assign to channel
+ * \param requestor channel asking for data
+ * \param addr destination of the call
+ * \param cause Cause of failure
+ *
+ * \details
+ * Request a channel of a given type, with addr as optional information used
+ * by the low level module
+ *
+ * \retval NULL failure
+ * \retval non-NULL channel on success
+ */
+ struct ast_channel *(* const requester_with_stream_topology)(const char *type, struct ast_stream_topology *topology, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *addr, int *cause);
+
+
int (* const devicestate)(const char *device_number); /*!< Devicestate call back */
int (* const presencestate)(const char *presence_provider, char **subtype, char **message); /*!< Presencestate callback */
@@ -664,9 +687,33 @@ struct ast_channel_tech {
/*! \brief Answer the channel */
int (* const answer)(struct ast_channel *chan);
- /*! \brief Read a frame, in standard format (see frame.h) */
+ /*!
+ * \brief Read a frame (or chain of frames from the same stream), in standard format (see frame.h)
+ *
+ * \param chan channel to read frames from
+ *
+ * \retval non-NULL on success
+ * \retval NULL on failure
+ *
+ * \note Each media frame from this callback will have the stream_num of it changed to the default
+ * stream num based on the type of media returned. As a result a multistream capable channel
+ * should not implement this callback.
+ */
struct ast_frame * (* const read)(struct ast_channel *chan);
+ /*!
+ * \brief Read a frame (or chain of frames from the same stream), in standard format (see frame.h), with stream num
+ *
+ * \param chan channel to read frames from
+ *
+ * \retval non-NULL on success
+ * \retval NULL on failure
+ *
+ * \note Each media frame from this callback should contain a stream_num value which is set to the
+ * stream that the media frame originated from.
+ */
+ struct ast_frame * (* const read_stream)(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);
@@ -887,10 +934,6 @@ enum {
* world
*/
AST_CHAN_TP_INTERNAL = (1 << 2),
- /*!
- * \brief Channels with this particular technology support multiple simultaneous streams
- */
- AST_CHAN_TP_MULTISTREAM = (1 << 3),
};
/*! \brief ast_channel flags */
@@ -1373,6 +1416,25 @@ struct ast_channel *ast_channel_release(struct ast_channel *chan);
*/
struct ast_channel *ast_request(const char *type, struct ast_format_cap *request_cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *addr, int *cause);
+/*!
+ * \brief Requests a channel (specifying stream topology)
+ *
+ * \param type type of channel to request
+ * \param topology Stream topology for requested channel
+ * \param assignedids Unique ID to create channel with
+ * \param requestor channel asking for data
+ * \param addr destination of the call
+ * \param cause Cause of failure
+ *
+ * \details
+ * Request a channel of a given type, with addr as optional information used
+ * by the low level module
+ *
+ * \retval NULL failure
+ * \retval non-NULL channel on success
+ */
+struct ast_channel *ast_request_with_stream_topology(const char *type, struct ast_stream_topology *topology, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *addr, int *cause);
+
enum ast_channel_requestor_relationship {
/*! The requestor is the future bridge peer of the channel. */
AST_CHANNEL_REQUESTOR_BRIDGE_PEER,
@@ -1926,14 +1988,37 @@ int ast_waitfor_n_fd(int *fds, int n, int *ms, int *exception);
/*!
* \brief Reads a frame
+ *
* \param chan channel to read a frame from
+ *
* \return Returns a frame, or NULL on error. If it returns NULL, you
* best just stop reading frames and assume the channel has been
* disconnected.
+ *
+ * \note This function will filter frames received from the channel so
+ * that only frames from the default stream for each media type
+ * are returned. All other media frames from other streams will
+ * be absorbed internally and a NULL frame returned instead.
*/
struct ast_frame *ast_read(struct ast_channel *chan);
/*!
+ * \brief Reads a frame, but does not filter to just the default streams
+ *
+ * \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 This function will not perform any filtering and will return
+ * media frames from all streams on the channel. To determine which
+ * stream a frame originated from the stream_num on it can be
+ * examined.
+ */
+struct ast_frame *ast_read_stream(struct ast_channel *chan);
+
+/*!
* \brief Reads a frame, returning AST_FRAME_NULL frame if audio.
* \param chan channel to read a frame from
* \return Returns a frame, or NULL on error. If it returns NULL, you
@@ -1945,6 +2030,26 @@ struct ast_frame *ast_read(struct ast_channel *chan);
struct ast_frame *ast_read_noaudio(struct ast_channel *chan);
/*!
+ * \brief Reads a frame, but does not filter to just the default streams,
+ * returning AST_FRAME_NULL frame if audio.
+ *
+ * \param chan channel to read a frame from
+ *
+ * \return Returns a frame, or NULL on error. If it returns NULL, you
+ * best just stop reading frames and assume the channel has been
+ * disconnected.
+ *
+ * \note This function will not perform any filtering and will return
+ * media frames from all streams on the channel. To determine which
+ * stream a frame originated from the stream_num on it can be
+ * examined.
+ *
+ * \note Audio is replaced with AST_FRAME_NULL to avoid
+ * transcode when the resulting audio is not necessary.
+ */
+struct ast_frame *ast_read_stream_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
@@ -2134,11 +2239,12 @@ int ast_waitfordigit(struct ast_channel *c, int ms);
* 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 (<0 for indefinite).
+ * \param breakon string of DTMF digits to break upon or NULL for any.
* \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);
+int ast_waitfordigit_full(struct ast_channel *c, int ms, const char *breakon, int audiofd, int ctrlfd);
/*!
* \brief Reads multiple digits
@@ -2359,12 +2465,6 @@ void ast_channel_set_caller_event(struct ast_channel *chan, const struct ast_par
/*! Set the file descriptor on the channel */
void ast_channel_set_fd(struct ast_channel *chan, int which, int fd);
-/*! Add a channel to an optimized waitfor */
-void ast_poll_channel_add(struct ast_channel *chan0, struct ast_channel *chan1);
-
-/*! Delete a channel from an optimized waitfor */
-void ast_poll_channel_del(struct ast_channel *chan0, struct ast_channel *chan1);
-
/*! Start a tone going */
int ast_tonepair_start(struct ast_channel *chan, int freq1, int freq2, int duration, int vol);
/*! Stop a tone from playing */
@@ -3760,27 +3860,6 @@ int ast_channel_connected_line_macro(struct ast_channel *autoservice_chan, struc
int ast_channel_connected_line_sub(struct ast_channel *autoservice_chan, struct ast_channel *sub_chan, const void *connected_info, int frame);
/*!
- * \brief Insert into an astdata tree, the channel structure.
- * \param[in] tree The ast data tree.
- * \param[in] chan The channel structure to add to tree.
- * \param[in] add_bridged Add the bridged channel to the structure.
- * \retval <0 on error.
- * \retval 0 on success.
- */
-int ast_channel_data_add_structure(struct ast_data *tree, struct ast_channel *chan, int add_bridged);
-
-/*!
- * \brief Compare to channel structures using the data api.
- * \param[in] tree The search tree generated by the data api.
- * \param[in] chan The channel to compare.
- * \param[in] structure_name The name of the node of the channel structure.
- * \retval 0 The structure matches.
- * \retval 1 The structure doesn't matches.
- */
-int ast_channel_data_cmp_structure(const struct ast_data_search *tree, struct ast_channel *chan,
- const char *structure_name);
-
-/*!
* \since 1.8
* \brief Run a redirecting interception macro and update a channel's redirecting information
* \deprecated You should use the ast_channel_redirecting_sub() function instead.
@@ -4230,12 +4309,6 @@ struct ast_namedgroups *ast_channel_named_pickupgroups(const struct ast_channel
void ast_channel_named_pickupgroups_set(struct ast_channel *chan, struct ast_namedgroups *value);
/* Alertpipe accessors--the "internal" functions for channel.c use only */
-typedef enum {
- AST_ALERT_READ_SUCCESS = 0,
- AST_ALERT_NOT_READABLE,
- AST_ALERT_READ_FAIL,
- AST_ALERT_READ_FATAL,
-} ast_alert_status_t;
int ast_channel_alert_write(struct ast_channel *chan);
int ast_channel_alert_writable(struct ast_channel *chan);
ast_alert_status_t ast_channel_internal_alert_flush(struct ast_channel *chan);
@@ -4257,11 +4330,30 @@ void ast_channel_internal_fd_set(struct ast_channel *chan, int which, int value)
int ast_channel_fd(const struct ast_channel *chan, int which);
int ast_channel_fd_isset(const struct ast_channel *chan, int which);
-/* epoll data internal accessors */
-#ifdef HAVE_EPOLL
-struct ast_epoll_data *ast_channel_internal_epfd_data(const struct ast_channel *chan, int which);
-void ast_channel_internal_epfd_data_set(struct ast_channel *chan, int which , struct ast_epoll_data *value);
-#endif
+/*!
+ * \since 15
+ * \brief Retrieve the number of file decriptor positions present on the channel
+ *
+ * \param chan The channel to get the count of
+ *
+ * \pre chan is locked
+ *
+ * \return The number of file descriptor positions
+ */
+int ast_channel_fd_count(const struct ast_channel *chan);
+
+/*!
+ * \since 15
+ * \brief Add a file descriptor to the channel without a fixed position
+ *
+ * \param chan The channel to add the file descriptor to
+ * \param value The file descriptor
+ *
+ * \pre chan is locked
+ *
+ * \return The position of the file descriptor
+ */
+int ast_channel_fd_add(struct ast_channel *chan, int value);
pthread_t ast_channel_blocker(const struct ast_channel *chan);
void ast_channel_blocker_set(struct ast_channel *chan, pthread_t value);
@@ -4345,6 +4437,31 @@ void ast_channel_dialed_causes_clear(const struct ast_channel *chan);
struct ast_flags *ast_channel_flags(struct ast_channel *chan);
/*!
+ * \since 13.17.0
+ * \brief Set a flag on a channel
+ *
+ * \param chan The channel to set the flag on
+ * \param flag The flag to set
+ *
+ * \note This will lock the channel internally. If the channel is already
+ * locked it is still safe to call.
+ */
+
+void ast_channel_set_flag(struct ast_channel *chan, unsigned int flag);
+
+/*!
+ * \since 13.17.0
+ * \param Clear a flag on a channel
+ *
+ * \param chan The channel to clear the flag from
+ * \param flag The flag to clear
+ *
+ * \note This will lock the channel internally. If the channel is already
+ * locked it is still safe to call.
+ */
+void ast_channel_clear_flag(struct ast_channel *chan, unsigned int flag);
+
+/*!
* \since 12.4.0
* \brief Return whether or not any manager variables have been set
*
@@ -4548,6 +4665,9 @@ struct ast_bridge_channel *ast_channel_get_bridge_channel(struct ast_channel *ch
*
* \note absolutely _NO_ channel locks should be held before calling this function.
*
+ * \note The dialplan location on the returned channel is where the channel
+ * should be started in the dialplan if it is returned to it.
+ *
* \param yankee The channel to gain control of
* \retval NULL Could not gain control of the channel
* \retval non-NULL The channel
@@ -4796,4 +4916,63 @@ struct ast_stream_topology *ast_channel_set_stream_topology(
*/
struct ast_stream *ast_channel_get_default_stream(struct ast_channel *chan, enum ast_media_type type);
+/*!
+ * \brief Determine if a channel is multi-stream capable
+ *
+ * \param channel The channel to test
+ *
+ * \pre chan is locked
+ *
+ * \return Returns true if the channel is multi-stream capable.
+ */
+int ast_channel_is_multistream(struct ast_channel *chan);
+
+/*!
+ * \brief Request that the stream topology of a channel change
+ *
+ * \param chan The channel to change
+ * \param topology The new stream topology
+ * \param change_source The source that initiated the change
+ *
+ * \note Absolutely _NO_ channel locks should be held before calling this function.
+ *
+ * \retval 0 request has been accepted to be attempted
+ * \retval -1 request could not be attempted
+ *
+ * \note This function initiates an asynchronous request to change the stream topology. It is not
+ * guaranteed that the topology will change and until an AST_CONTROL_STREAM_TOPOLOGY_CHANGED
+ * frame is received from the channel the current handler of the channel must tolerate the
+ * stream topology as it currently exists.
+ *
+ * \note This interface is provided for applications and resources to request that the topology change.
+ * It is not for use by the channel driver itself.
+ */
+int ast_channel_request_stream_topology_change(struct ast_channel *chan,
+ struct ast_stream_topology *topology, void *change_source);
+
+/*!
+ * \brief Provide notice to a channel that the stream topology has changed
+ *
+ * \param chan The channel to provide notice to
+ * \param topology The new stream topology
+ *
+ * \pre chan is locked Absolutely _NO_ other channels can be locked.
+ *
+ * \retval 0 success
+ * \retval -1 failure
+ *
+ * \note This interface is provided for applications and resources to accept a topology change.
+ * It is not for use by the channel driver itself.
+ */
+int ast_channel_stream_topology_changed(struct ast_channel *chan, struct ast_stream_topology *topology);
+
+/*!
+ * \brief Retrieve the source that initiated the last stream topology change
+ *
+ * \param chan The channel
+ *
+ * \retval The channel's stream topology change source
+ */
+void *ast_channel_get_stream_topology_change_source(struct ast_channel *chan);
+
#endif /* _ASTERISK_CHANNEL_H */
diff --git a/include/asterisk/channel_internal.h b/include/asterisk/channel_internal.h
index 3de2b14aa..dd791a416 100644
--- a/include/asterisk/channel_internal.h
+++ b/include/asterisk/channel_internal.h
@@ -29,5 +29,7 @@ void ast_channel_internal_errno_set(enum ast_channel_error error);
enum ast_channel_error ast_channel_internal_errno(void);
void ast_channel_internal_set_stream_topology(struct ast_channel *chan,
struct ast_stream_topology *topology);
+void ast_channel_internal_set_stream_topology_change_source(
+ struct ast_channel *chan, void *change_source);
void ast_channel_internal_swap_stream_topology(struct ast_channel *chan1,
struct ast_channel *chan2);
diff --git a/include/asterisk/codec.h b/include/asterisk/codec.h
index 2ae955181..79798acd0 100644
--- a/include/asterisk/codec.h
+++ b/include/asterisk/codec.h
@@ -76,6 +76,8 @@ struct ast_codec {
int (*get_length)(unsigned int samples);
/*! \brief Whether the media can be smoothed or not */
unsigned int smooth;
+ /*! \brief Flags to be passed to the smoother */
+ unsigned int smoother_flags;
/*! \brief The module that registered this codec */
struct ast_module *mod;
};
@@ -166,6 +168,17 @@ int ast_codec_get_max(void);
const char *ast_codec_media_type2str(enum ast_media_type type);
/*!
+ * \brief Conversion function to take a media string and convert it to a media type
+ *
+ * \param media_type_str The media type string
+ *
+ * \retval The ast_media_type that corresponds to the string
+ *
+ * \since 15.0.0
+ */
+enum ast_media_type ast_media_type_from_str(const char *media_type_str);
+
+/*!
* \brief Get the number of samples contained within a frame
*
* \param frame The frame itself
diff --git a/include/asterisk/compat.h b/include/asterisk/compat.h
index 252ce914a..88f88cf8b 100644
--- a/include/asterisk/compat.h
+++ b/include/asterisk/compat.h
@@ -27,35 +27,18 @@
#define __STDC_VERSION__ 0
#endif
-#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
-#endif
-
-#ifdef HAVE_LIMITS_H
#include <limits.h>
-#endif
-
-#ifdef HAVE_UNISTD_H
#include <unistd.h>
-#endif
#ifdef HAVE_STDDEF_H
#include <stddef.h>
#endif
-#ifdef HAVE_STDINT_H
#include <stdint.h>
-#endif
-
-#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
-#endif
-
#include <stdarg.h>
-
-#ifdef HAVE_STDLIB_H
#include <stdlib.h>
-#endif
#ifdef HAVE_ALLOCA_H
#include <alloca.h> /* not necessarily present - could be in stdlib */
@@ -65,9 +48,7 @@
#include <stdio.h> /* this is always present */
-#ifdef HAVE_STRING_H
#include <string.h>
-#endif
#ifndef AST_POLL_COMPAT
#include <poll.h>
@@ -158,7 +139,6 @@ void timersub(struct timeval *tvend, struct timeval *tvstart, struct timeval *tv
#include <alloca.h>
#include <strings.h>
-#include <string.h>
#include <pthread.h>
#include <sys/stat.h>
#include <signal.h>
diff --git a/include/asterisk/config.h b/include/asterisk/config.h
index f57966b0b..1addfa317 100644
--- a/include/asterisk/config.h
+++ b/include/asterisk/config.h
@@ -1086,6 +1086,11 @@ enum ast_parse_flags {
PARSE_UINT16 = 0x0005,
#endif
+ /* Returns an int processed by ast_app_parse_timelen.
+ * The first argument is an enum ast_timelen value (required).
+ */
+ PARSE_TIMELEN = 0x0006,
+
/* Returns a struct ast_sockaddr, with optional default value
* (passed by reference) and port handling (accept, ignore,
* require, forbid). The format is 'ipaddress[:port]'. IPv6 address
@@ -1152,6 +1157,12 @@ enum ast_parse_flags {
* returns 1, b unchanged
* ast_parse_arg("12", PARSE_UINT32|PARSE_IN_RANGE|PARSE_RANGE_DEFAULTS, &a, 1, 10);
* returns 1, a = 10
+ * ast_parse_arg("223", PARSE_TIMELEN|PARSE_IN_RANGE, &a, TIMELEN_SECONDS, -1000, 1000);
+ * returns 0, a = 1000
+ * ast_parse_arg("223", PARSE_TIMELEN|PARSE_IN_RANGE, &a, TIMELEN_SECONDS, -1000, 250000);
+ * returns 0, a = 223000
+ * ast_parse_arg("223", PARSE_TIMELEN|PARSE_IN_RANGE|PARSE_DEFAULT, &a, TIMELEN_SECONDS, 9999, -1000, 250000);
+ * returns 0, a = 9999
* ast_parse_arg("www.foo.biz:44", PARSE_INADDR, &sa);
* returns 0, sa contains address and port
* ast_parse_arg("www.foo.biz", PARSE_INADDR|PARSE_PORT_REQUIRE, &sa);
diff --git a/include/asterisk/config_options.h b/include/asterisk/config_options.h
index f2a457eb5..f4c3db188 100644
--- a/include/asterisk/config_options.h
+++ b/include/asterisk/config_options.h
@@ -468,6 +468,30 @@ enum aco_option_type {
*/
OPT_YESNO_T,
+ /*! \brief Type for default option handler for time length signed integers
+ *
+ * \note aco_option_register flags:
+ * See flags available for use with the PARSE_TIMELEN type for the ast_parse_arg function
+ * aco_option_register varargs:
+ * FLDSET macro with the field of type int
+ * The remaining varargs for should be arguments compatible with the varargs for the
+ * ast_parse_arg function with the PARSE_TIMELEN type and the flags passed in the
+ * aco_option_register flags parameter.
+ *
+ * \note In most situations, it is preferable to not pass the PARSE_DEFAULT flag. If a config
+ * contains an invalid value, it is better to let the config loading fail with warnings so that
+ * the problem is fixed by the administrator.
+ *
+ * Example:
+ * struct test_item {
+ * int timelen;
+ * };
+ * {code}
+ * aco_option_register(&cfg_info, "timelen", ACO_EXACT, my_types, "3", OPT_TIMELEN_T, PARSE_IN_RANGE, FLDSET(struct test_item, intopt), TIMELEN_MILLISECONDS, -10, 10);
+ * {endcode}
+ */
+ OPT_TIMELEN_T,
+
};
/*! \brief A callback function for handling a particular option
diff --git a/include/asterisk/conversions.h b/include/asterisk/conversions.h
new file mode 100644
index 000000000..2997760a8
--- /dev/null
+++ b/include/asterisk/conversions.h
@@ -0,0 +1,62 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2017, Digium, Inc.
+ *
+ * Kevin Harwell <kharwell@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 Conversion utility functions
+ */
+
+#ifndef _ASTERISK_CONVERSIONS_H
+#define _ASTERISK_CONVERSIONS_H
+
+/*!
+ * \brief Convert the given string to an unsigned integer
+ *
+ * This function will return failure for the following reasons:
+ *
+ * The given string to convert is NULL
+ * The given string to convert is empty.
+ * The given string to convert is negative (starts with a '-')
+ * The given string to convert contains non numeric values
+ * Once converted the number is out of range (greater than UINT_MAX)
+ *
+ * \param str The string to convert
+ * \param res [out] The converted value
+ *
+ * \returns -1 if it fails to convert, 0 on success
+ */
+int ast_str_to_uint(const char *str, unsigned int *res);
+
+/*!
+ * \brief Convert the given string to an unsigned long
+ *
+ * This function will return failure for the following reasons:
+ *
+ * The given string to convert is NULL
+ * The given string to convert is empty.
+ * The given string to convert is negative (starts with a '-')
+ * The given string to convert contains non numeric values
+ * Once converted the number is out of range (greater than ULONG_MAX)
+ *
+ * \param str The string to convert
+ * \param res [out] The converted value
+ *
+ * \returns -1 if it fails to convert, 0 on success
+ */
+int ast_str_to_ulong(const char *str, unsigned long *res);
+
+#endif /* _ASTERISK_CONVERSIONS_H */
diff --git a/include/asterisk/core_local.h b/include/asterisk/core_local.h
index 8557072c6..27e924477 100644
--- a/include/asterisk/core_local.h
+++ b/include/asterisk/core_local.h
@@ -42,36 +42,37 @@ struct stasis_message_type;
/* ------------------------------------------------------------------- */
/*!
- * \brief Lock the "chan" and "owner" channels (and return them) on the base
- * private structure as well as the base private structure itself.
+ * \brief Add a reference to the local channel's private tech, lock the local channel's
+ * private base, and add references and lock both sides of the local channel.
*
- * \note This also adds references to each of the above mentioned elements and
- * also the underlying private local structure.
* \note None of these locks should be held prior to calling this function.
- * \note To undo this process call ast_local_unlock_all.
+ * \note To undo this process call ast_local_unlock_all2.
*
- * \since 13.8.0
+ * \since 13.17.0, 14.6.0
*
* \param chan Must be a local channel
- * \param outchan The local channel's "chan" channel
- * \param outowner The local channel's "owner" channel
+ * \param tech_pvt [out] channel's private tech (ref and lock added)
+ * \param base_chan [out] One side of the local channel (ref and lock added)
+ * \param base_owner [out] Other side of the local channel (ref and lock added)
*/
-void ast_local_lock_all(struct ast_channel *chan, struct ast_channel **outchan,
- struct ast_channel **outowner);
+void ast_local_lock_all(struct ast_channel *chan, void **tech_pvt,
+ struct ast_channel **base_chan, struct ast_channel **base_owner);
/*!
- * \brief Unlock the "chan" and "owner" channels on the base private structure
- * as well as the base private structure itself.
+ * \brief Remove a reference to the given local channel's private tech, unlock the given
+ * local channel's private base, and remove references and unlock both sides of
+ * given the local channel.
*
- * \note This also removes references to each of the above mentioned elements and
- * also the underlying private local structure.
- * \note This function should be used in conjunction with ast_local_lock_all.
+ * \note This function should be used in conjunction with ast_local_lock_all2.
*
- * \since 13.8.0
+ * \since 13.17.0, 14.6.0
*
- * \param chan Must be a local channel
+ * \param tech_pvt channel's private tech (ref and lock removed)
+ * \param base_chan One side of the local channel (ref and lock removed)
+ * \param base_owner Other side of the local channel (ref and lock removed)
*/
-void ast_local_unlock_all(struct ast_channel *chan);
+void ast_local_unlock_all(void *tech_pvt, struct ast_channel *base_chan,
+ struct ast_channel *base_owner);
/*!
* \brief Get the other local channel in the pair.
diff --git a/include/asterisk/data.h b/include/asterisk/data.h
deleted file mode 100644
index d6da1f7d6..000000000
--- a/include/asterisk/data.h
+++ /dev/null
@@ -1,828 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2009, Eliel C. Sardanons (LU1ALY) <eliels@gmail.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 Data retrieval API.
- * \author Brett Bryant <brettbryant@gmail.com>
- * \author Eliel C. Sardanons (LU1ALY) <eliels@gmail.com>
- * \arg \ref AstDataRetrieval
- */
-
-#ifndef ASTERISK_DATA_H
-#define ASTERISK_DATA_H
-
-#include "asterisk/frame.h"
-#include "asterisk/format_cap.h"
-
-/*!
- * \page AstDataRetrieval The Asterisk DATA retrieval API.
- *
- * This module implements an abstraction for retrieving asterisk data and
- * export it.
- *
- * \section USAGE
- *
- * \subsection Provider
- *
- * \b Register
- *
- * To register a callback use:
- *
- * \code
- * static const struct ast_data_handler callback_handler = {
- * .get = callback_handler_get_function,
- * };
- *
- * ast_data_register("/node/path", &callback_handler);
- * \endcode
- *
- * If you instead want to register multiple nodes at once use:
- * \code
- * static const struct ast_data_handler handler_struct1 = {
- * .get = handler_callback_read,
- * };
- * ... other handlers ...
- *
- * static const struct ast_data_entry list_providers[] = {
- * AST_DATA_ENTRY("/path1/node1", &handler_struct1),
- * AST_DATA_ENTRY("/path2/node2", &handler_struct2),
- * AST_DATA_ENTRY("/path3/node3", &handler_struct3),
- * };
- *
- * ...
- *
- * ast_data_register_multiple(list_providers, ARRAY_LEN(list_providers));
- * \endcode
- *
- * \b Unregister
- *
- * To unregister a callback function already registered you can just call:
- *
- * \code
- * ast_data_unregister(NULL);
- * \endcode
- * And every node registered by the current module (file) will be unregistered.
- * If you want to unregister a specific node use:
- *
- * \code
- * ast_data_unregister("/node/path");
- * \endcode
- *
- * \b Implementation
- *
- * A simple callback function implementation:
- *
- * \code
- * #include <data.h>
- *
- * struct test_structure {
- * int a;
- * double b;
- * };
- *
- * DATA_EXPORT_TEST_STRUCTURE(MEMBER) \
- * MEMBER(test_structure, a, AST_DATA_INTEGER) \
- * MEMBER(test_structure, b, AST_DATA_DOUBLE)
- *
- * AST_DATA_STRUCTURE(test_structure, DATA_EXPORT_TEST_STRUCTURE)
- *
- * static int my_callback_function(struct ast_data_search *search,
- * struct ast_data *root_node)
- * {
- * struct ast_data *internal_node;
- * struct test_structure ts = {
- * .a = 10,
- * .b = 20
- * };
- *
- * internal_node = ast_data_add_node(root_node, "test_node");
- * if (!internal_node) {
- * return -1;
- * }
- *
- * ast_data_add_structure(test_structure, internal_node, ts);
- *
- * if (!ast_data_search_match(search, internal_node)) {
- * ast_data_remove_node(root_node, internal_node);
- * }
- *
- * return 0;
- * }
- *
- * \endcode
- *
- * \subsection Get
- *
- * \b Getting \b the \b tree
- *
- * To get the tree you need to create a query, a query is based on three parameters
- * a \b path to the provider, a \b search condition and a \b filter condition.
- * \code
- * struct ast_data *result;
- * struct ast_data_query query = {
- * .path = "/asterisk/application/app_queue/queues",
- * .search = "/queues/queue/name=queue1",
- * .filter = "/queues/queue/name|wrapuptime|members/member/interface"
- * };
- *
- * result = ast_data_get(&query);
- * \endcode
- *
- * After using it you need to release the allocated memory of the returned tree:
- * \code
- * ast_data_free(result);
- * \endcode
- *
- * \b Iterate
- *
- * To retrieve nodes from the tree, it is possible to iterate through the returned
- * nodes of the tree using:
- * \code
- * struct ast_data_iterator *i;
- * struct ast_data *internal_node;
- *
- * i = ast_data_iterator_init(result_tree, "path/node_name");
- * while ((internal_node = ast_data_iterator_next(i))) {
- * ... do something with node ...
- * }
- * ast_data_iterator_end(i);
- * \endcode
- * node_name is the name of the nodes to retrieve and path is the path to the internal
- * nodes to retrieve (if needed).
- *
- * \b Retrieving
- *
- * After getting the node you where searching for, you will need to retrieve its value,
- * to do that you may use one of the ast_data_retrieve_##type functions:
- * \code
- * int a = ast_data_retrieve_int(tree, "path/to/the/node");
- * double b = ast_data_retrieve_dbl(tree, "path/to/the/node");
- * unsigned int c = ast_data_retrieve_bool(tree, "path/to/the/node");
- * char *d = ast_data_retrieve_string(tree, "path/to/the/node");
- * struct sockaddr_in e = ast_data_retrieve_ipaddr(tree, "path/to/the/node");
- * unsigned int f = ast_data_retrieve_uint(tree, "path/to/the/node");
- * void *g = ast_data_retrieve_ptr(tree, "path/to/the/node");
- * \endcode
- *
- */
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-/*! \brief The data type of the data node. */
-enum ast_data_type {
- AST_DATA_CONTAINER,
- AST_DATA_INTEGER,
- AST_DATA_UNSIGNED_INTEGER,
- AST_DATA_DOUBLE,
- AST_DATA_BOOLEAN,
- AST_DATA_STRING,
- AST_DATA_CHARACTER,
- AST_DATA_PASSWORD,
- AST_DATA_IPADDR,
- AST_DATA_TIMESTAMP,
- AST_DATA_SECONDS,
- AST_DATA_MILLISECONDS,
- AST_DATA_POINTER
-};
-
-/*! \brief The Data API structures version. */
-#define AST_DATA_HANDLER_VERSION 1
-#define AST_DATA_QUERY_VERSION 1
-
-/*! \brief opaque definition of an ast_data handler, a tree node. */
-struct ast_data;
-
-/*! \brief opaque definition of an ast_data_iterator handler. */
-struct ast_data_iterator;
-
-/*! \brief opaque definition of an ast_data_search structure. */
-struct ast_data_search;
-
-/*! \brief structure retrieved from a node, with the nodes content. */
-struct ast_data_retrieve {
- /*! \brief The type of the node retrieved. */
- enum ast_data_type type;
-
- union {
- char AST_DATA_CHARACTER;
- char *AST_DATA_STRING;
- char *AST_DATA_PASSWORD;
- int AST_DATA_INTEGER;
- unsigned int AST_DATA_TIMESTAMP;
- unsigned int AST_DATA_SECONDS;
- unsigned int AST_DATA_MILLISECONDS;
- double AST_DATA_DOUBLE;
- unsigned int AST_DATA_UNSIGNED_INTEGER;
- unsigned int AST_DATA_BOOLEAN;
- void *AST_DATA_POINTER;
- struct in_addr AST_DATA_IPADDR;
- void *AST_DATA_CONTAINER;
- } value;
-};
-
-/*!
- * \brief The get callback definition.
- */
-typedef int (*ast_data_get_cb)(const struct ast_data_search *search,
- struct ast_data *root);
-
-/*! \brief The structure of the node handler. */
-struct ast_data_handler {
- /*! \brief Structure version. */
- uint32_t version;
- /*! \brief Data get callback implementation. */
- ast_data_get_cb get;
-};
-
-/*! \brief This entries are for multiple registers. */
-struct ast_data_entry {
- /*! \brief Path of the node to register. */
- const char *path;
- /*! \brief Data handler structure. */
- const struct ast_data_handler *handler;
-};
-
-#define AST_DATA_ENTRY(__path, __handler) { .path = __path, .handler = __handler }
-
-/*! \brief A query to the data API is specified in this structure. */
-struct ast_data_query {
- /*! \brief Data query version. */
- uint32_t version;
- /*! \brief Path to the node to retrieve. */
- char *path;
- /*! \brief Filter string, return the internal nodes specified here.
- * Setting it to NULL will return every internal node. */
- char *filter;
- /*! \brief Search condition. */
- char *search;
-};
-
-/*! \brief Map the members of a structure. */
-struct ast_data_mapping_structure {
- /*! \brief structure member name. */
- const char *name;
- /*! \brief structure member type. */
- enum ast_data_type type;
- /*! \brief member getter. */
- union {
- char (*AST_DATA_CHARACTER)(void *ptr);
- char *(*AST_DATA_STRING)(void *ptr);
- char *(*AST_DATA_PASSWORD)(void *ptr);
- int (*AST_DATA_INTEGER)(void *ptr);
- int (*AST_DATA_TIMESTAMP)(void *ptr);
- int (*AST_DATA_SECONDS)(void *ptr);
- int (*AST_DATA_MILLISECONDS)(void *ptr);
- double (*AST_DATA_DOUBLE)(void *ptr);
- unsigned int (*AST_DATA_UNSIGNED_INTEGER)(void *ptr);
- unsigned int (*AST_DATA_BOOLEAN)(void *ptr);
- void *(*AST_DATA_POINTER)(void *ptr);
- struct in_addr (*AST_DATA_IPADDR)(void *ptr);
- void *(*AST_DATA_CONTAINER)(void *ptr);
- } get;
-};
-
-/* Generate the structure and the functions to access the members of a structure. */
-#define AST_DATA_STRUCTURE(__struct, __name) \
- __name(__AST_DATA_MAPPING_FUNCTION); \
- static const struct ast_data_mapping_structure __data_mapping_structure_##__struct[] = { \
- __name(__AST_DATA_MAPPING_STRUCTURE) \
- }
-
-/* Generate the structure to access the members and setup the pointer of the getter. */
-#define __AST_DATA_MAPPING_STRUCTURE(__structure, __member, __type) \
- { .name = #__member, .get.__type = data_mapping_structure_get_##__structure##__member, \
- .type = __type },
-
-/* based on the data type, specifify the type of return value for the getter function. */
-#define __AST_DATA_MAPPING_FUNCTION_AST_DATA_PASSWORD(__structure, __member) \
- __AST_DATA_MAPPING_FUNCTION_TYPE(__structure, __member, AST_DATA_PASSWORD, char *)
-#define __AST_DATA_MAPPING_FUNCTION_AST_DATA_STRING(__structure, __member) \
- __AST_DATA_MAPPING_FUNCTION_TYPE(__structure, __member, AST_DATA_STRING, char *)
-#define __AST_DATA_MAPPING_FUNCTION_AST_DATA_CHARACTER(__structure, __member) \
- __AST_DATA_MAPPING_FUNCTION_TYPE(__structure, __member, AST_DATA_CHARACTER, char)
-#define __AST_DATA_MAPPING_FUNCTION_AST_DATA_INTEGER(__structure, __member) \
- __AST_DATA_MAPPING_FUNCTION_TYPE(__structure, __member, AST_DATA_INTEGER, int)
-#define __AST_DATA_MAPPING_FUNCTION_AST_DATA_TIMESTAMP(__structure, __member) \
- __AST_DATA_MAPPING_FUNCTION_TYPE(__structure, __member, AST_DATA_INTEGER, int)
-#define __AST_DATA_MAPPING_FUNCTION_AST_DATA_SECONDS(__structure, __member) \
- __AST_DATA_MAPPING_FUNCTION_TYPE(__structure, __member, AST_DATA_INTEGER, int)
-#define __AST_DATA_MAPPING_FUNCTION_AST_DATA_MILLISECONDS(__structure, __member) \
- __AST_DATA_MAPPING_FUNCTION_TYPE(__structure, __member, AST_DATA_INTEGER, int)
-#define __AST_DATA_MAPPING_FUNCTION_AST_DATA_UNSIGNED_INTEGER(__structure, __member) \
- __AST_DATA_MAPPING_FUNCTION_TYPE(__structure, __member, AST_DATA_UNSIGNED_INTEGER, unsigned int)
-#define __AST_DATA_MAPPING_FUNCTION_AST_DATA_BOOLEAN(__structure, __member) \
- __AST_DATA_MAPPING_FUNCTION_TYPE(__structure, __member, AST_DATA_BOOLEAN, unsigned int)
-#define __AST_DATA_MAPPING_FUNCTION_AST_DATA_POINTER(__structure, __member) \
- __AST_DATA_MAPPING_FUNCTION_TYPE(__structure, __member, AST_DATA_POINTER, void *)
-#define __AST_DATA_MAPPING_FUNCTION_AST_DATA_IPADDR(__structure, __member) \
- __AST_DATA_MAPPING_FUNCTION_TYPE(__structure, __member, AST_DATA_IPADDR, struct in_addr)
-#define __AST_DATA_MAPPING_FUNCTION_AST_DATA_DOUBLE(__structure, __member) \
- __AST_DATA_MAPPING_FUNCTION_TYPE(__structure, __member, AST_DATA_DBL, double)
-#define __AST_DATA_MAPPING_FUNCTION_AST_DATA_CONTAINER(__structure, __member) \
- __AST_DATA_MAPPING_FUNCTION_TYPE(__structure, __member, AST_DATA_CONTAINER, void *)
-
-#define __AST_DATA_MAPPING_FUNCTION(__structure, __member, __type) \
- __AST_DATA_MAPPING_FUNCTION_##__type(__structure, __member)
-
-/* Create the function to retrieve a member of the structure. */
-#define __AST_DATA_MAPPING_FUNCTION_TYPE(__structure, __member, __type, __real_type) \
- static __real_type data_mapping_structure_get_##__structure##__member(void *ptr) { \
- struct __structure *struct_##__member = (struct __structure *) ptr; \
- return (__real_type) struct_##__member->__member; \
- }
-
-/*!
- * \brief Register a data provider.
- * \param[in] path The path of the node to register.
- * \param[in] handler The structure defining this node handler.
- * \param[in] registrar Who is registering this node.
- * \param[in] mod The module registering this handler.
- * \see ast_data_unregister
- * \retval <0 on error.
- * \retval 0 on success.
- * \see __ast_data_unregister, __ast_data_register_multiple
- */
-int __ast_data_register(const char *path, const struct ast_data_handler *handler,
- const char *registrar, struct ast_module *mod);
-#define ast_data_register(path, handler) __ast_data_register(path, handler, __FILE__, AST_MODULE_SELF)
-#define ast_data_register_core(path, handler) __ast_data_register(path, handler, __FILE__, NULL)
-
-/*!
- * \brief Register multiple data providers at once.
- * \param[in] data_entries An array of data_entries structures.
- * \param[in] entries The number of entries in the data_entries array.
- * \param[in] registrar Who is registering this nodes.
- * \param[in] mod The module registering this handlers.
- * \retval <0 on error (none of the nodes are being registered on error).
- * \retval 0 on success.
- * \see __ast_data_register, __ast_data_unregister
- */
-int __ast_data_register_multiple(const struct ast_data_entry *data_entries,
- size_t entries, const char *registrar, struct ast_module *mod);
-#define ast_data_register_multiple(data_entries, entries) \
- __ast_data_register_multiple(data_entries, entries, __FILE__, AST_MODULE_SELF)
-#define ast_data_register_multiple_core(data_entries, entries) \
- __ast_data_register_multiple(data_entries, entries, __FILE__, NULL)
-
-/*!
- * \brief Unregister a data provider.
- * \param[in] path Which node to unregister, if path is NULL unregister every node
- * registered by the passed 'registrar'.
- * \param[in] registrar Who is trying to unregister this node, only the owner (the
- * one who registered the node) will be able to unregister it.
- * \see ast_data_register
- * \retval <0 on error.
- * \retval 0 on success.
- * \see __ast_data_register, __ast_data_register_multiple
- */
-int __ast_data_unregister(const char *path, const char *registrar);
-#define ast_data_unregister(path) __ast_data_unregister(path, __FILE__)
-
-/*!
- * \brief Check the current generated node to know if it matches the search
- * condition.
- * \param[in] search The search condition.
- * \param[in] data The AstData node generated.
- * \return 1 If the "data" node matches the search condition.
- * \return 0 If the "data" node does not matches the search condition.
- * \see ast_data_remove_node
- */
-int ast_data_search_match(const struct ast_data_search *search, struct ast_data *data);
-
-/*!
- * \brief Based on a search tree, evaluate every member of a structure against it.
- * \param[in] search The search tree.
- * \param[in] mapping The structure mapping.
- * \param[in] mapping_len The lenght of the structure mapping.
- * \param[in] structure The structure pointer.
- * \param[in] structure_name The name of the structure to compare.
- * \retval 0 If the structure matches.
- * \retval 1 If the structure doesn't match.
- */
-int __ast_data_search_cmp_structure(const struct ast_data_search *search,
- const struct ast_data_mapping_structure *mapping, size_t mapping_len,
- void *structure, const char *structure_name);
-#define ast_data_search_cmp_structure(search, structure_name, structure, structure_name_cmp) \
- __ast_data_search_cmp_structure(search, __data_mapping_structure_##structure_name, \
- ARRAY_LEN(__data_mapping_structure_##structure_name), structure, structure_name_cmp)
-
-/*!
- * \brief Retrieve a subtree from the asterisk data API.
- * \param[in] query The query structure specifying what nodes to retrieve.
- * \retval NULL on error.
- * \retval non-NULL The dynamically allocated requested sub-tree (it needs to be
- * released using ast_data_free.
- * \see ast_data_free, ast_data_get_xml
- */
-struct ast_data *ast_data_get(const struct ast_data_query *query);
-
-#ifdef HAVE_LIBXML2
-/*!
- * \brief Retrieve a subtree from the asterisk data API in XML format..
- * \param[in] query The query structure specifying what nodes to retrieve.
- * \retval NULL on error.
- * \retval non-NULL The dynamically allocated requested sub-tree (it needs to be
- * released using ast_data_free.
- * \see ast_data_free, ast_data_get
- */
-struct ast_xml_doc *ast_data_get_xml(const struct ast_data_query *query);
-#endif
-
-/*!
- * \brief Release the allocated memory of a tree.
- * \param[in] root The sub-tree pointer returned by a call to ast_data_get.
- * \see ast_data_get
- */
-void ast_data_free(struct ast_data *root);
-
-/*!
- * \brief Get a node type.
- * \param[in] res A pointer to the ast_data result set.
- * \param[in] path A path to the node to get the type.
- * \return The type of the requested node type.
- */
-enum ast_data_type ast_data_retrieve_type(struct ast_data *res, const char *path);
-
-/*!
- * \brief Get the node name.
- * \param[in] node The node pointer.
- * \returns The node name.
- */
-char *ast_data_retrieve_name(struct ast_data *node);
-
-/*!
- * \brief Add a container child.
- * \param[in] root The root of the ast_data to insert into.
- * \param[in] childname The name of the child element to be added.
- * \retval NULL on error (memory exhaustion only).
- * \retval non-NULL a newly allocated node.
- */
-struct ast_data *ast_data_add_node(struct ast_data *root, const char *childname);
-
-/*!
- * \brief Add an integer node type.
- * \param[in] root The root of the ast_data to insert into.
- * \param[in] childname The name of the child element to be added.
- * \param[in] value The value for the new node.
- * \retval NULL on error (memory exhaustion only).
- * \retval non-NULL a newly allocated node.
- */
-struct ast_data *ast_data_add_int(struct ast_data *root, const char *childname,
- int value);
-
-/*!
- * \brief Add a char node type.
- * \param[in] root The root of the ast_data to insert into.
- * \param[in] childname The name of the child element to be added.
- * \param[in] value The value for the new node.
- * \retval NULL on error (memory exhaustion only).
- * \retval non-NULL a newly allocated node.
- */
-struct ast_data *ast_data_add_char(struct ast_data *root, const char *childname,
- char value);
-
-/*!
- * \brief Add an unsigned integer node type.
- * \param[in] root The root of the ast_data to insert into.
- * \param[in] childname The name of the child element to be added.
- * \param[in] value The value for the new node.
- * \retval NULL on error (memory exhaustion only).
- * \retval non-NULL a newly allocated node.
- */
-struct ast_data *ast_data_add_uint(struct ast_data *root, const char *childname,
- unsigned int value);
-
-/*!
- * \brief Add a floating point node type.
- * \param[in] root The root of the ast_data to insert into.
- * \param[in] childname The name of the child element to be added.
- * \param[in] dbl The value for the new node.
- * \retval NULL on error (memory exhaustion only).
- * \retval non-NULL a newly allocated node.
- */
-struct ast_data *ast_data_add_dbl(struct ast_data *root, const char *childname,
- double dbl);
-/*!
- * \brief Add a ipv4 address type.
- * \param[in] root The root of the ast_data to insert into.
- * \param[in] childname The name of the child element to be added.
- * \param[in] addr The ipv4 address value.
- * \retval NULL on error (memory exhaustion only).
- * \retval non-NULL a newly allocated node.
- */
-struct ast_data *ast_data_add_ipaddr(struct ast_data *root, const char *childname,
- struct in_addr addr);
-
-/*!
- * \brief Add a ptr node type.
- * \param[in] root The root of the ast_data to insert into.
- * \param[in] childname The name of the child element to be added.
- * \param[in] ptr The pointer value to add.
- * \retval NULL on error (memory exhaustion only).
- * \retval non-NULL a newly allocated node.
- */
-struct ast_data *ast_data_add_ptr(struct ast_data *root, const char *childname,
- void *ptr);
-
-/*!
- * \brief Add a password node type.
- * \param[in] root The root of the ast_data to insert into.
- * \param[in] childname The name of the child element to be added.
- * \param[in] string The value for the new node.
- * \retval NULL on error (memory exhaustion only).
- * \retval non-NULL a newly allocated node.
- */
-struct ast_data *ast_data_add_password(struct ast_data *root, const char *childname,
- const char *string);
-
-/*!
- * \brief Add a timestamp node type.
- * \param[in] root The root of the ast_data to insert into.
- * \param[in] childname The name of the child element to be added.
- * \param[in] timestamp The value for the new node.
- * \retval NULL on error (memory exhaustion only).
- * \retval non-NULL a newly allocated node.
- */
-struct ast_data *ast_data_add_timestamp(struct ast_data *root, const char *childname,
- unsigned int timestamp);
-
-/*!
- * \brief Add a seconds node type.
- * \param[in] root The root of the ast_data to insert into.
- * \param[in] childname The name of the child element to be added.
- * \param[in] seconds The value for the new node.
- * \retval NULL on error (memory exhaustion only).
- * \retval non-NULL a newly allocated node.
- */
-struct ast_data *ast_data_add_seconds(struct ast_data *root, const char *childname,
- unsigned int seconds);
-
-/*!
- * \brief Add a milliseconds node type.
- * \param[in] root The root of the ast_data to insert into.
- * \param[in] childname The name of the child element to be added.
- * \param[in] milliseconds The value for the new node.
- * \retval NULL on error (memory exhaustion only).
- * \retval non-NULL a newly allocated node.
- */
-struct ast_data *ast_data_add_milliseconds(struct ast_data *root, const char *childname,
- unsigned int milliseconds);
-
-/*!
- * \brief Add a string node type.
- * \param[in] root The root of the ast_data to insert into.
- * \param[in] childname The name of the child element to be added.
- * \param[in] string The value for the new node.
- * \retval NULL on error (memory exhaustion only).
- * \retval non-NULL a newly allocated node.
- */
-struct ast_data *ast_data_add_str(struct ast_data *root, const char *childname,
- const char *string);
-
-/*!
- * \brief Add a boolean node type.
- * \param[in] root The root of the ast_data to insert into.
- * \param[in] childname The name of the child element to be added.
- * \param[in] boolean The value for the new node.
- * \retval NULL on error (memory exhaustion only).
- * \retval non-NULL a newly allocated node.
- */
-struct ast_data *ast_data_add_bool(struct ast_data *root, const char *childname,
- unsigned int boolean);
-
-/*!
- * \brief Add a complete structure to a node.
- * \param[in] root Where to add the structure.
- * \param[in] mapping The structure mapping array.
- * \param[in] mapping_len The lenght of the mapping array.
- * \param[in] structure The structure pointer.
- * \retval 0 on success.
- * \retval 1 on error.
- */
-int __ast_data_add_structure(struct ast_data *root,
- const struct ast_data_mapping_structure *mapping,
- size_t mapping_len, void *structure);
-#define ast_data_add_structure(structure_name, root, structure) \
- __ast_data_add_structure(root, __data_mapping_structure_##structure_name, \
- ARRAY_LEN(__data_mapping_structure_##structure_name), structure)
-
-/*!
- * \brief Remove a node that was added using ast_data_add_
- * \param[in] root The root node of the node to be removed.
- * \param[in] child The node pointer to remove.
- */
-void ast_data_remove_node(struct ast_data *root, struct ast_data *child);
-
-/*!
- * \brief Initialize an iterator.
- * \param[in] tree The returned tree by a call to ast_data_get.
- * \param[in] elements Which elements to iterate through.
- * \retval NULL on error.
- * \retval non-NULL A dinamically allocated iterator structure.
- */
-struct ast_data_iterator *ast_data_iterator_init(struct ast_data *tree,
- const char *elements);
-
-/*!
- * \brief Release (stop using) an iterator.
- * \param[in] iterator The iterator created by ast_data_iterator_start.
- * \see ast_data_iterator_start
- */
-void ast_data_iterator_end(struct ast_data_iterator *iterator);
-
-/*!
- * \brief Get the next node of the tree.
- * \param[in] iterator The iterator structure returned by ast_data_iterator_start.
- * \retval NULL when no more nodes to return.
- * \retval non-NULL A node of the ast_data tree.
- * \see ast_data_iterator_start, ast_data_iterator_stop
- */
-struct ast_data *ast_data_iterator_next(struct ast_data_iterator *iterator);
-
-/*!
- * \brief Retrieve a value from a node in the tree.
- * \param[in] tree The structure returned by a call to ast_data_get.
- * \param[in] path The path to the node.
- * \param[out] content The node content.
- * \retval 0 on success.
- * \retval <0 on error.
- */
-int ast_data_retrieve(struct ast_data *tree, const char *path, struct ast_data_retrieve *content);
-
-/*!
- * \brief Retrieve the integer value of a node.
- * \param[in] tree The tree from where to get the value.
- * \param[in] path The node name or path.
- * \returns The value of the node.
- */
-static inline int ast_data_retrieve_int(struct ast_data *tree, const char *path)
-{
- struct ast_data_retrieve ret;
-
- ast_data_retrieve(tree, path, &ret);
-
- return ret.value.AST_DATA_INTEGER;
-}
-
-/*!
- * \brief Retrieve the character value of a node.
- * \param[in] tree The tree from where to get the value.
- * \param[in] path The node name or path.
- * \returns The value of the node.
- */
-static inline char ast_data_retrieve_char(struct ast_data *tree, const char *path)
-{
- struct ast_data_retrieve ret;
-
- ast_data_retrieve(tree, path, &ret);
-
- return ret.value.AST_DATA_CHARACTER;
-}
-
-/*!
- * \brief Retrieve the boolean value of a node.
- * \param[in] tree The tree from where to get the value.
- * \param[in] path The node name or path.
- * \returns The value of the node.
- */
-static inline unsigned int ast_data_retrieve_bool(struct ast_data *tree, const char *path)
-{
- struct ast_data_retrieve ret;
-
- ast_data_retrieve(tree, path, &ret);
-
- return ret.value.AST_DATA_BOOLEAN;
-}
-
-/*!
- * \brief Retrieve the unsigned integer value of a node.
- * \param[in] tree The tree from where to get the value.
- * \param[in] path The node name or path.
- * \returns The value of the node.
- */
-static inline unsigned int ast_data_retrieve_uint(struct ast_data *tree, const char *path)
-{
- struct ast_data_retrieve ret;
-
- ast_data_retrieve(tree, path, &ret);
-
- return ret.value.AST_DATA_UNSIGNED_INTEGER;
-}
-
-/*!
- * \brief Retrieve the password value of a node.
- * \param[in] tree The tree from where to get the value.
- * \param[in] path The node name or path.
- * \returns The value of the node.
- */
-static inline const char *ast_data_retrieve_password(struct ast_data *tree, const char *path)
-{
- struct ast_data_retrieve ret;
-
- ast_data_retrieve(tree, path, &ret);
-
- return ret.value.AST_DATA_PASSWORD;
-}
-
-/*!
- * \brief Retrieve the string value of a node.
- * \param[in] tree The tree from where to get the value.
- * \param[in] path The node name or path.
- * \returns The value of the node.
- */
-static inline const char *ast_data_retrieve_string(struct ast_data *tree, const char *path)
-{
- struct ast_data_retrieve ret;
-
- ast_data_retrieve(tree, path, &ret);
-
- return ret.value.AST_DATA_STRING;
-}
-
-/*!
- * \brief Retrieve the ptr value of a node.
- * \param[in] tree The tree from where to get the value.
- * \param[in] path The node name or path.
- * \returns The value of the node.
- */
-static inline void *ast_data_retrieve_ptr(struct ast_data *tree, const char *path)
-{
- struct ast_data_retrieve ret;
-
- ast_data_retrieve(tree, path, &ret);
-
- return ret.value.AST_DATA_POINTER;
-}
-
-/*!
- * \brief Retrieve the double value of a node.
- * \param[in] tree The tree from where to get the value.
- * \param[in] path The node name or path.
- * \returns The value of the node.
- */
-static inline double ast_data_retrieve_dbl(struct ast_data *tree, const char *path)
-{
- struct ast_data_retrieve ret;
-
- ast_data_retrieve(tree, path, &ret);
-
- return ret.value.AST_DATA_DOUBLE;
-}
-
-/*!
- * \brief Retrieve the ipv4 address value of a node.
- * \param[in] tree The tree from where to get the value.
- * \param[in] path The node name or path.
- * \returns The value of the node.
- */
-static inline struct in_addr ast_data_retrieve_ipaddr(struct ast_data *tree, const char *path)
-{
- struct ast_data_retrieve ret;
-
- ast_data_retrieve(tree, path, &ret);
-
- return ret.value.AST_DATA_IPADDR;
-}
-
-/*!
- * \brief Add the codec in the root node based on the format parameter.
- * \param[in] root The astdata root node where to add the codec node.
- * \param[in] node_name The name of the node where we are going to add the codec.
- * \param[in] format The codec allowed.
- * \return < 0 on error.
- * \return 0 on success.
- */
-int ast_data_add_codec(struct ast_data *root, const char *node_name, struct ast_format *format);
-
-/*!
- * \brief Add the list of codecs in the root node based on the capability parameter.
- * \param[in] root The astdata root node where to add the codecs node.
- * \param[in] node_name The name of the node where we are going to add the list of
- * codecs.
- * \param[in] capability The codecs allowed.
- * \return < 0 on error.
- * \return 0 on success.
- */
-int ast_data_add_codecs(struct ast_data *root, const char *node_name, struct ast_format_cap *capability);
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}
-#endif
-
-#endif /* ASTERISK_DATA_H */
diff --git a/include/asterisk/features_config.h b/include/asterisk/features_config.h
index baaff183b..1bce50bba 100644
--- a/include/asterisk/features_config.h
+++ b/include/asterisk/features_config.h
@@ -117,6 +117,21 @@ struct ast_features_xfer_config *ast_get_chan_features_xfer_config(struct ast_ch
char *ast_get_chan_features_xferfailsound(struct ast_channel *chan);
/*!
+ * \brief Get the transfer configuration option atxferabort
+ *
+ * \note The channel should be locked before calling this function.
+ * \note The returned value has to be freed.
+ *
+ * If no channel is provided, then option is pulled from the global
+ * transfer configuration.
+ *
+ * \param chan The channel to get configuration options for
+ * \retval NULL Failed to get configuration
+ * \retval non-NULL The atxferabort
+ */
+char *ast_get_chan_features_atxferabort(struct ast_channel *chan);
+
+/*!
* \brief Configuration relating to call pickup
*/
struct ast_features_pickup_config {
diff --git a/include/asterisk/format.h b/include/asterisk/format.h
index b01592d16..946c03d98 100644
--- a/include/asterisk/format.h
+++ b/include/asterisk/format.h
@@ -32,7 +32,7 @@ struct ast_format;
/*! \brief Format comparison results */
enum ast_format_cmp_res {
- /*! Both formats are equivalent to eachother */
+ /*! Both formats are equivalent to each other */
AST_FORMAT_CMP_EQUAL = 0,
/*! Both formats are completely different and not the same in any way */
AST_FORMAT_CMP_NOT_EQUAL,
@@ -110,7 +110,7 @@ struct ast_format_interface {
struct ast_format *(* const format_parse_sdp_fmtp)(const struct ast_format *format, const char *attributes);
/*!
- * \brief Generate SDP attribute information from an ast_format_attr structure.
+ * \brief Generate SDP attribute information from an ast_format structure.
*
* \param format The format containing attributes
* \param payload The payload number to place into the fmtp line
@@ -356,6 +356,17 @@ const char *ast_format_get_codec_name(const struct ast_format *format);
int ast_format_can_be_smoothed(const struct ast_format *format);
/*!
+ * \since 13.17.0
+ *
+ * \brief Get smoother flags for this format
+ *
+ * \param format The media format
+ *
+ * \return smoother flags for the provided format
+ */
+int ast_format_get_smoother_flags(const struct ast_format *format);
+
+/*!
* \brief Get the media type of a format
*
* \param format The media format
diff --git a/include/asterisk/format_cache.h b/include/asterisk/format_cache.h
index 6099c59ea..067546310 100644
--- a/include/asterisk/format_cache.h
+++ b/include/asterisk/format_cache.h
@@ -184,6 +184,11 @@ extern struct ast_format *ast_format_mp4;
extern struct ast_format *ast_format_vp8;
/*!
+ * \brief Built-in cached vp9 format.
+ */
+extern struct ast_format *ast_format_vp9;
+
+/*!
* \brief Built-in cached jpeg format.
*/
extern struct ast_format *ast_format_jpeg;
@@ -224,6 +229,11 @@ extern struct ast_format *ast_format_t140;
extern struct ast_format *ast_format_t140_red;
/*!
+ * \brief Built-in cached T.38 format.
+ */
+extern struct ast_format *ast_format_t38;
+
+/*!
* \brief Built-in "null" format.
*/
extern struct ast_format *ast_format_none;
diff --git a/include/asterisk/frame.h b/include/asterisk/frame.h
index 90f8aa086..eb6a6479a 100644
--- a/include/asterisk/frame.h
+++ b/include/asterisk/frame.h
@@ -137,6 +137,8 @@ enum {
AST_FRFLAG_HAS_TIMING_INFO = (1 << 0),
/*! This frame has been requeued */
AST_FRFLAG_REQUEUED = (1 << 1),
+ /*! This frame contains a valid sequence number */
+ AST_FRFLAG_HAS_SEQUENCE_NUMBER = (1 << 2),
};
struct ast_frame_subclass {
@@ -181,6 +183,8 @@ struct ast_frame {
long len;
/*! Sequence number */
int seqno;
+ /*! Stream number the frame originated from */
+ int stream_num;
};
/*!
@@ -295,6 +299,9 @@ enum ast_control_frame_type {
AST_CONTROL_UPDATE_RTP_PEER = 32, /*!< Interrupt the bridge and have it update the peer */
AST_CONTROL_PVT_CAUSE_CODE = 33, /*!< Contains an update to the protocol-specific cause-code stored for branching dials */
AST_CONTROL_MASQUERADE_NOTIFY = 34, /*!< A masquerade is about to begin/end. (Never sent as a frame but directly with ast_indicate_data().) */
+ AST_CONTROL_STREAM_TOPOLOGY_REQUEST_CHANGE = 35, /*!< Channel indication that a stream topology change has been requested */
+ AST_CONTROL_STREAM_TOPOLOGY_CHANGED = 36, /*!< Channel indication that a stream topology change has occurred */
+ AST_CONTROL_STREAM_TOPOLOGY_SOURCE_CHANGED = 37, /*!< Channel indication that one of the source streams has changed its source */
/*
* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
diff --git a/include/asterisk/indications.h b/include/asterisk/indications.h
index b02be1fdf..309954b05 100644
--- a/include/asterisk/indications.h
+++ b/include/asterisk/indications.h
@@ -28,7 +28,6 @@
#include "asterisk/astobj2.h"
#include "asterisk/utils.h"
-#include "asterisk/data.h"
/*!
* \brief Description of a tone
@@ -242,12 +241,4 @@ static inline struct ast_tone_zone_sound *ast_tone_zone_sound_ref(struct ast_ton
return ts;
}
-/*!
- * \brief Add a tone_zone structure to the data tree specified.
- *
- * \retval <0 on error.
- * \retval 0 on success.
- */
-int ast_tone_zone_data_add_structure(struct ast_data *tree, struct ast_tone_zone *zone);
-
#endif /* _ASTERISK_INDICATIONS_H */
diff --git a/include/asterisk/io.h b/include/asterisk/io.h
index 6ee8450bd..f103cf556 100644
--- a/include/asterisk/io.h
+++ b/include/asterisk/io.h
@@ -24,6 +24,7 @@
#define _ASTERISK_IO_H
#include "asterisk/poll-compat.h"
+#include "asterisk/netsock2.h"
#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
@@ -148,6 +149,29 @@ int ast_get_termcols(int fd);
*/
int ast_sd_notify(const char *state);
+/*!
+ * \brief Find a listening file descriptor provided by socket activation.
+ * \param type SOCK_STREAM or SOCK_DGRAM
+ * \param addr The socket address of the bound listener.
+ * \retval <0 No match.
+ * \retval >0 File Descriptor matching sockaddr.
+ *
+ * \note This function returns -1 if systemd's development headers were not
+ * detected on the system.
+ */
+int ast_sd_get_fd(int type, const struct ast_sockaddr *addr);
+
+/*!
+ * \brief Find a listening AF_LOCAL file descriptor provided by socket activation.
+ * \param type SOCK_STREAM or SOCK_DGRAM
+ * \param path The path of the listener.
+ * \retval <0 No match.
+ * \retval >0 File Descriptor matching path.
+ *
+ * \note This function returns -1 if systemd's development headers were not
+ * detected on the system.
+ */
+int ast_sd_get_fd_un(int type, const char *path);
#if defined(__cplusplus) || defined(c_plusplus)
}
diff --git a/include/asterisk/lock.h b/include/asterisk/lock.h
index 5b6817f6b..58c9a8383 100644
--- a/include/asterisk/lock.h
+++ b/include/asterisk/lock.h
@@ -240,13 +240,8 @@ enum ast_lock_type {
* 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.
*/
-#ifdef HAVE_BKTR
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, struct ast_bt *bt);
-#else
-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);
-#endif /* HAVE_BKTR */
/*!
* \brief Mark the last lock as acquired
@@ -264,11 +259,7 @@ void ast_mark_lock_failed(void *lock_addr);
* this gets called by ast_mutex_unlock so that information on the lock can
* be removed from the current thread's lock info struct.
*/
-#ifdef HAVE_BKTR
void ast_remove_lock_info(void *lock_addr, struct ast_bt *bt);
-#else
-void ast_remove_lock_info(void *lock_addr);
-#endif /* HAVE_BKTR */
void ast_suspend_lock_info(void *lock_addr);
void ast_restore_lock_info(void *lock_addr);
diff --git a/include/asterisk/logger.h b/include/asterisk/logger.h
index 9f9f671c0..8b1e5fe01 100644
--- a/include/asterisk/logger.h
+++ b/include/asterisk/logger.h
@@ -429,7 +429,9 @@ void ast_callid_strnprint(char *buffer, size_t buffer_size, ast_callid callid);
#define DEBUG_ATLEAST(level) \
(option_debug >= (level) \
- || (ast_opt_dbg_module && (int)ast_debug_get_by_module(AST_MODULE) >= (level)))
+ || (ast_opt_dbg_module \
+ && ((int)ast_debug_get_by_module(AST_MODULE) >= (level) \
+ || (int)ast_debug_get_by_module(__FILE__) >= (level))))
/*!
* \brief Log a DEBUG message
@@ -500,6 +502,29 @@ int ast_verb_console_get(void);
*/
void ast_verb_console_set(int verb_level);
+/*!
+ * \brief Test if logger is initialized
+ *
+ * \retval true if the logger is initialized
+ */
+int ast_is_logger_initialized(void);
+
+/*!
+ * \brief Set the maximum number of messages allowed in the processing queue
+ *
+ * \param queue_limit
+ *
+ * \return Nothing
+ */
+void ast_logger_set_queue_limit(int queue_limit);
+
+/*!
+ * \brief Get the maximum number of messages allowed in the processing queue
+ *
+ * \return Queue limit
+ */
+int ast_logger_get_queue_limit(void);
+
#if defined(__cplusplus) || defined(c_plusplus)
}
#endif
diff --git a/include/asterisk/manager.h b/include/asterisk/manager.h
index 60c51de85..67dcead47 100644
--- a/include/asterisk/manager.h
+++ b/include/asterisk/manager.h
@@ -54,7 +54,7 @@
- \ref manager.c Main manager code file
*/
-#define AMI_VERSION "3.1.0"
+#define AMI_VERSION "4.0.0"
#define DEFAULT_MANAGER_PORT 5038 /* Default port for Asterisk management via TCP */
#define DEFAULT_MANAGER_TLS_PORT 5039 /* Default port for Asterisk management via TCP */
diff --git a/include/asterisk/module.h b/include/asterisk/module.h
index a80c7f843..69ebb2640 100644
--- a/include/asterisk/module.h
+++ b/include/asterisk/module.h
@@ -94,6 +94,20 @@ enum ast_module_support_level {
AST_MODULE_SUPPORT_DEPRECATED,
};
+/*! Used to specify which modules should be returned by ast_module_helper. */
+enum ast_module_helper_type {
+ /*! Modules that are loaded by dlopen. */
+ AST_MODULE_HELPER_LOADED = 0,
+ /*! Running modules that include a reload callback. */
+ AST_MODULE_HELPER_RELOAD = 1,
+ /*! Modules that can be loaded or started. */
+ AST_MODULE_HELPER_LOAD,
+ /*! Modules that can be unloaded. */
+ AST_MODULE_HELPER_UNLOAD,
+ /*! Running modules */
+ AST_MODULE_HELPER_RUNNING,
+};
+
/*!
* \brief Load a module.
* \param resource_name The name of the module to load.
@@ -237,14 +251,12 @@ int ast_loader_unregister(int (*updater)(void));
* \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.
+ * \param type The type of action that will be performed by CLI.
*
* \retval A possible completion of the partial match.
* \retval NULL if no matches were found.
*/
-char *ast_module_helper(const char *line, const char *word, int pos, int state, int rpos, int needsreload);
+char *ast_module_helper(const char *line, const char *word, int pos, int state, int rpos, enum ast_module_helper_type type);
/* Opaque type for module handles generated by the loader */
@@ -303,8 +315,6 @@ struct ast_module_info {
enum ast_module_load_result (*load)(void); /*!< register stuff etc. Optional. */
int (*reload)(void); /*!< config etc. Optional. */
int (*unload)(void); /*!< unload. called with the module locked */
- int (*backup_globals)(void); /*!< for embedded modules, backup global data */
- void (*restore_globals)(void); /*!< for embedded modules, restore global data */
const char *name; /*!< name of the module for loader reference and CLI commands */
const char *description; /*!< user friendly description of the module. */
@@ -379,8 +389,6 @@ void __ast_module_unref(struct ast_module *mod, const char *file, int line, cons
load_func, \
reload_func, \
unload_func, \
- NULL, \
- NULL, \
AST_MODULE, \
desc, \
keystr, \
@@ -440,70 +448,9 @@ void __ast_module_unref(struct ast_module *mod, const char *file, int line, cons
static const __attribute__((unused)) struct ast_module_info *ast_module_info;
#endif
-#if !defined(EMBEDDED_MODULE)
-#define __MODULE_INFO_SECTION
-#define __MODULE_INFO_GLOBALS
-#else
-/*
- * For embedded modules we need additional information to backup and
- * restore the global variables in the module itself, so we can unload
- * reload the module.
- * EMBEDDED_MODULE is defined as the module name, so the calls to make_var()
- * below will actually define different symbols for each module.
- */
-#define __MODULE_INFO_SECTION __attribute__((section(".embed_module")))
-#define __MODULE_INFO_GLOBALS .backup_globals = __backup_globals, .restore_globals = __restore_globals,
-
-#define make_var_sub(mod, type) __ ## mod ## _ ## type
-#define make_var(mod, type) make_var_sub(mod, type)
-
-extern void make_var(EMBEDDED_MODULE, bss_start);
-extern void make_var(EMBEDDED_MODULE, bss_end);
-extern void make_var(EMBEDDED_MODULE, data_start);
-extern void make_var(EMBEDDED_MODULE, data_end);
-
-static void * __attribute__((section(".embed_module"))) __global_backup;
-
-static int __backup_globals(void)
-{
- size_t data_size = & make_var(EMBEDDED_MODULE, data_end) - & make_var(EMBEDDED_MODULE, data_start);
-
- if (__global_backup)
- return 0;
-
- if (!data_size)
- return 0;
-
- if (!(__global_backup = ast_malloc(data_size)))
- return -1;
-
- memcpy(__global_backup, & make_var(EMBEDDED_MODULE, data_start), data_size);
-
- return 0;
-}
-
-static void __restore_globals(void)
-{
- size_t data_size = & make_var(EMBEDDED_MODULE, data_end) - & make_var(EMBEDDED_MODULE, data_start);
- size_t bss_size = & make_var(EMBEDDED_MODULE, bss_end) - & make_var(EMBEDDED_MODULE, bss_start);
-
- if (bss_size)
- memset(& make_var(EMBEDDED_MODULE, bss_start), 0, bss_size);
-
- if (!data_size || !__global_backup)
- return;
-
- memcpy(& make_var(EMBEDDED_MODULE, data_start), __global_backup, data_size);
-}
-#undef make_var
-#undef make_var_sub
-#endif /* EMBEDDED_MODULE */
-
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...) \
static struct ast_module_info \
- __MODULE_INFO_SECTION \
__mod_info = { \
- __MODULE_INFO_GLOBALS \
.name = AST_MODULE, \
.flags = flags_to_set, \
.description = desc, \
diff --git a/include/asterisk/netsock2.h b/include/asterisk/netsock2.h
index 3ede99087..6c0dd633b 100644
--- a/include/asterisk/netsock2.h
+++ b/include/asterisk/netsock2.h
@@ -129,6 +129,22 @@ static inline void ast_sockaddr_setnull(struct ast_sockaddr *addr)
}
/*!
+ * \brief
+ * Copies the data from a sockaddr to an ast_sockaddr
+ *
+ * \param dst The destination ast_sockaddr
+ * \param src The source sockaddr
+ * \param len Length of the value stored in sockaddr
+ * \retval void
+ */
+static inline void ast_sockaddr_copy_sockaddr(struct ast_sockaddr *dst,
+ struct sockaddr *src, socklen_t len)
+{
+ memcpy(dst, src, len);
+ dst->len = len;
+}
+
+/*!
* \since 1.8
*
* \brief
diff --git a/include/asterisk/network.h b/include/asterisk/network.h
index 3371e5895..5216f4c61 100644
--- a/include/asterisk/network.h
+++ b/include/asterisk/network.h
@@ -86,6 +86,11 @@ const char *ast_inet_ntoa(struct in_addr ia);
#endif
#define inet_ntoa __dont__use__inet_ntoa__use__ast_inet_ntoa__instead__
+#ifdef getprotobyname
+#undef getprotobyname
+#endif
+#define getprotobyname __getprotobyname_is_not_threadsafe__do_not_use__
+
/*! \brief Compares the source address and port of two sockaddr_in */
static force_inline int inaddrcmp(const struct sockaddr_in *sin1, const struct sockaddr_in *sin2)
{
diff --git a/include/asterisk/options.h b/include/asterisk/options.h
index 05ad6c560..878748d16 100644
--- a/include/asterisk/options.h
+++ b/include/asterisk/options.h
@@ -66,6 +66,8 @@ enum ast_option_flags {
AST_OPT_FLAG_CACHE_RECORD_FILES = (1 << 13),
/*! Display timestamp in CLI verbose output */
AST_OPT_FLAG_TIMESTAMP = (1 << 14),
+ /*! Cache media frames for performance */
+ AST_OPT_FLAG_CACHE_MEDIA_FRAMES = (1 << 15),
/*! Reconnect */
AST_OPT_FLAG_RECONNECT = (1 << 16),
/*! Transmit Silence during Record() and DTMF Generation */
@@ -99,7 +101,7 @@ enum ast_option_flags {
};
/*! These are the options that set by default when Asterisk starts */
-#define AST_DEFAULT_OPTIONS AST_OPT_FLAG_TRANSCODE_VIA_SLIN
+#define AST_DEFAULT_OPTIONS (AST_OPT_FLAG_TRANSCODE_VIA_SLIN | AST_OPT_FLAG_CACHE_MEDIA_FRAMES)
#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)
@@ -116,6 +118,7 @@ enum ast_option_flags {
#define ast_opt_stdexten_macro ast_test_flag(&ast_options, AST_OPT_FLAG_STDEXTEN_MACRO)
#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_cache_media_frames ast_test_flag(&ast_options, AST_OPT_FLAG_CACHE_MEDIA_FRAMES)
#define ast_opt_timestamp ast_test_flag(&ast_options, AST_OPT_FLAG_TIMESTAMP)
#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)
@@ -196,6 +199,7 @@ extern int dahdi_chan_name_len;
extern int ast_language_is_prefix;
+extern int ast_option_rtpusedynamic;
extern unsigned int ast_option_rtpptdynamic;
#if defined(__cplusplus) || defined(c_plusplus)
diff --git a/include/asterisk/res_hep.h b/include/asterisk/res_hep.h
index cfd213ad7..dba86e88b 100644
--- a/include/asterisk/res_hep.h
+++ b/include/asterisk/res_hep.h
@@ -72,6 +72,8 @@ struct hepv3_capture_info {
size_t len;
/*! If non-zero, the payload accompanying this capture info will be compressed */
unsigned int zipped:1;
+ /*! The IPPROTO_* protocol where we captured the packet */
+ int protocol_id;
};
/*!
diff --git a/include/asterisk/res_pjsip.h b/include/asterisk/res_pjsip.h
index 09ace0775..e71eb98d7 100644
--- a/include/asterisk/res_pjsip.h
+++ b/include/asterisk/res_pjsip.h
@@ -98,22 +98,41 @@ struct ast_sip_transport_state {
*/
pj_ssl_cipher ciphers[SIP_TLS_MAX_CIPHERS];
/*!
- * Optional local network information, used for NAT purposes
+ * Optional local network information, used for NAT purposes.
+ * "deny" (set) means that it's in the local network. Use the
+ * ast_sip_transport_is_nonlocal and ast_sip_transport_is_local
+ * macro's.
* \since 13.8.0
*/
struct ast_ha *localnet;
/*!
- * DNS manager for refreshing the external address
+ * DNS manager for refreshing the external signaling address
* \since 13.8.0
*/
- struct ast_dnsmgr_entry *external_address_refresher;
+ struct ast_dnsmgr_entry *external_signaling_address_refresher;
/*!
- * Optional external address information
+ * Optional external signaling address information
* \since 13.8.0
*/
- struct ast_sockaddr external_address;
+ struct ast_sockaddr external_signaling_address;
+ /*!
+ * DNS manager for refreshing the external media address
+ * \since 13.18.0
+ */
+ struct ast_dnsmgr_entry *external_media_address_refresher;
+ /*!
+ * Optional external signaling address information
+ * \since 13.18.0
+ */
+ struct ast_sockaddr external_media_address;
};
+#define ast_sip_transport_is_nonlocal(transport_state, addr) \
+ (!transport_state->localnet || ast_apply_ha(transport_state->localnet, addr) == AST_SENSE_ALLOW)
+
+#define ast_sip_transport_is_local(transport_state, addr) \
+ (transport_state->localnet && ast_apply_ha(transport_state->localnet, addr) != AST_SENSE_ALLOW)
+
/*
* \brief Transport to bind to
*/
@@ -194,6 +213,8 @@ struct ast_sip_transport {
int write_timeout;
/*! Allow reload */
int allow_reload;
+ /*! Automatically send requests out the same transport requests have come in on */
+ int symmetric_transport;
};
#define SIP_SORCERY_DOMAIN_ALIAS_TYPE "domain_alias"
@@ -258,6 +279,8 @@ struct ast_sip_contact {
AST_STRING_FIELD_EXTENDED(call_id);
/*! The name of the endpoint that added the contact */
AST_STRING_FIELD_EXTENDED(endpoint_name);
+ /*! If true delete the contact on Asterisk restart/boot */
+ int prune_on_boot;
};
#define CONTACT_STATUS "contact_status"
@@ -363,6 +386,8 @@ enum ast_sip_dtmf_mode {
AST_SIP_DTMF_INFO,
/*! Use SIP 4733 if supported by the other side or INBAND if not */
AST_SIP_DTMF_AUTO,
+ /*! Use SIP 4733 if supported by the other side or INFO DTMF (blech) if not */
+ AST_SIP_DTMF_AUTO_INFO,
};
/*!
@@ -412,6 +437,8 @@ enum ast_sip_endpoint_identifier_type {
AST_SIP_ENDPOINT_IDENTIFY_BY_USERNAME = (1 << 0),
/*! Identify based on user name in Auth header first, then From header */
AST_SIP_ENDPOINT_IDENTIFY_BY_AUTH_USERNAME = (1 << 1),
+ /*! Identify based on source IP address */
+ AST_SIP_ENDPOINT_IDENTIFY_BY_IP = (1 << 2),
};
AST_VECTOR(ast_sip_identify_by_vector, enum ast_sip_endpoint_identifier_type);
@@ -664,6 +691,8 @@ struct ast_sip_endpoint_media_configuration {
struct ast_sip_t38_configuration t38;
/*! Configured codecs */
struct ast_format_cap *codecs;
+ /*! Capabilities in topology form */
+ struct ast_stream_topology *topology;
/*! DSCP TOS bits for audio streams */
unsigned int tos_audio;
/*! Priority for audio streams */
@@ -676,6 +705,16 @@ struct ast_sip_endpoint_media_configuration {
unsigned int g726_non_standard;
/*! Bind the RTP instance to the media_address */
unsigned int bind_rtp_to_media_address;
+ /*! Use RTCP-MUX */
+ unsigned int rtcp_mux;
+ /*! Maximum number of audio streams to offer/accept */
+ unsigned int max_audio_streams;
+ /*! Maximum number of video streams to offer/accept */
+ unsigned int max_video_streams;
+ /*! Use BUNDLE */
+ unsigned int bundle;
+ /*! Enable webrtc settings and defaults */
+ unsigned int webrtc;
};
/*!
@@ -761,8 +800,20 @@ struct ast_sip_endpoint {
unsigned int preferred_codec_only;
/*! Do we allow an asymmetric RTP codec? */
unsigned int asymmetric_rtp_codec;
+ /*! Do we allow overlap dialling? */
+ unsigned int allow_overlap;
+ /*! Whether to notifies all the progress details on blind transfer */
+ unsigned int refer_blind_progress;
+ /*! Whether to notifies dialog-info 'early' on INUSE && RINGING state */
+ unsigned int notify_early_inuse_ringing;
+ /*! If set, we'll push incoming MWI NOTIFYs to stasis using this mailbox */
+ AST_STRING_FIELD_EXTENDED(incoming_mwi_mailbox);
};
+/*! URI parameter for symmetric transport */
+#define AST_SIP_X_AST_TXP "x-ast-txp"
+#define AST_SIP_X_AST_TXP_LEN 9
+
/*!
* \brief Initialize an auth vector with the configured values.
*
@@ -853,6 +904,17 @@ struct ast_sip_endpoint_identifier {
};
/*!
+ * \brief Contact retrieval filtering flags
+ */
+enum ast_sip_contact_filter {
+ /*! \brief Default filter flags */
+ AST_SIP_CONTACT_FILTER_DEFAULT = 0,
+
+ /*! \brief Return only reachable or unknown contacts */
+ AST_SIP_CONTACT_FILTER_REACHABLE = (1 << 0),
+};
+
+/*!
* \brief Register a SIP service in Asterisk.
*
* This is more-or-less a wrapper around pjsip_endpt_register_module().
@@ -865,7 +927,9 @@ struct ast_sip_endpoint_identifier {
* \retval 0 Success
* \retval -1 Failure
*/
-int ast_sip_register_service(pjsip_module *module);
+#define ast_sip_register_service(module) \
+ __ast_sip_register_service(module, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+int __ast_sip_register_service(pjsip_module *module, const char *file, int line, const char *func);
/*!
* This is the opposite of ast_sip_register_service(). Unregistering a
@@ -874,7 +938,9 @@ int ast_sip_register_service(pjsip_module *module);
*
* \param module The PJSIP module to unregister
*/
-void ast_sip_unregister_service(pjsip_module *module);
+#define ast_sip_unregister_service(module) \
+ __ast_sip_unregister_service(module, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+void __ast_sip_unregister_service(pjsip_module *module, const char *file, int line, const char *func);
/*!
* \brief Register a SIP authenticator
@@ -1038,6 +1104,18 @@ struct ast_sip_aor *ast_sip_location_retrieve_aor(const char *aor_name);
struct ast_sip_contact *ast_sip_location_retrieve_first_aor_contact(const struct ast_sip_aor *aor);
/*!
+ * \brief Retrieve the first bound contact for an AOR and filter based on flags
+ * \since 13.16.0
+ *
+ * \param aor Pointer to the AOR
+ * \param flags Filtering flags
+ * \retval NULL if no contacts available
+ * \retval non-NULL if contacts available
+ */
+struct ast_sip_contact *ast_sip_location_retrieve_first_aor_contact_filtered(const struct ast_sip_aor *aor,
+ unsigned int flags);
+
+/*!
* \brief Retrieve all contacts currently available for an AOR
*
* \param aor Pointer to the AOR
@@ -1052,6 +1130,23 @@ struct ast_sip_contact *ast_sip_location_retrieve_first_aor_contact(const struct
struct ao2_container *ast_sip_location_retrieve_aor_contacts(const struct ast_sip_aor *aor);
/*!
+ * \brief Retrieve all contacts currently available for an AOR and filter based on flags
+ * \since 13.16.0
+ *
+ * \param aor Pointer to the AOR
+ * \param flags Filtering flags
+ *
+ * \retval NULL if no contacts available
+ * \retval non-NULL if contacts available
+ *
+ * \warning
+ * Since this function prunes expired contacts before returning, it holds a named write
+ * lock on the aor. If you already hold the lock, call ast_sip_location_retrieve_aor_contacts_nolock instead.
+ */
+struct ao2_container *ast_sip_location_retrieve_aor_contacts_filtered(const struct ast_sip_aor *aor,
+ unsigned int flags);
+
+/*!
* \brief Retrieve all contacts currently available for an AOR without locking the AOR
* \since 13.9.0
*
@@ -1066,6 +1161,22 @@ struct ao2_container *ast_sip_location_retrieve_aor_contacts(const struct ast_si
struct ao2_container *ast_sip_location_retrieve_aor_contacts_nolock(const struct ast_sip_aor *aor);
/*!
+ * \brief Retrieve all contacts currently available for an AOR without locking the AOR and filter based on flags
+ * \since 13.16.0
+ *
+ * \param aor Pointer to the AOR
+ * \param flags Filtering flags
+ *
+ * \retval NULL if no contacts available
+ * \retval non-NULL if contacts available
+ *
+ * \warning
+ * This function should only be called if you already hold a named write lock on the aor.
+ */
+struct ao2_container *ast_sip_location_retrieve_aor_contacts_nolock_filtered(const struct ast_sip_aor *aor,
+ unsigned int flags);
+
+/*!
* \brief Retrieve the first bound contact from a list of AORs
*
* \param aor_list A comma-separated list of AOR names
@@ -1094,6 +1205,18 @@ struct ao2_container *ast_sip_location_retrieve_contacts_from_aor_list(const cha
struct ast_sip_contact **contact);
/*!
+ * \brief Retrieve the first bound contact AND the AOR chosen from a list of AORs and filter based on flags
+ * \since 13.16.0
+ *
+ * \param aor_list A comma-separated list of AOR names
+ * \param flags Filtering flags
+ * \param aor The chosen AOR
+ * \param contact The chosen contact
+ */
+void ast_sip_location_retrieve_contact_and_aor_from_list_filtered(const char *aor_list, unsigned int flags,
+ struct ast_sip_aor **aor, struct ast_sip_contact **contact);
+
+/*!
* \brief Retrieve a named contact
*
* \param contact_name Name of the contact
@@ -1111,6 +1234,9 @@ struct ast_sip_contact *ast_sip_location_retrieve_contact(const char *contact_na
* \param expiration_time Optional expiration time of the contact
* \param path_info Path information
* \param user_agent User-Agent header from REGISTER request
+ * \param via_addr
+ * \param via_port
+ * \param call_id
* \param endpoint The endpoint that resulted in the contact being added
*
* \retval -1 failure
@@ -1134,6 +1260,9 @@ int ast_sip_location_add_contact(struct ast_sip_aor *aor, const char *uri,
* \param expiration_time Optional expiration time of the contact
* \param path_info Path information
* \param user_agent User-Agent header from REGISTER request
+ * \param via_addr
+ * \param via_port
+ * \param call_id
* \param endpoint The endpoint that resulted in the contact being added
*
* \retval -1 failure
@@ -1148,6 +1277,31 @@ int ast_sip_location_add_contact_nolock(struct ast_sip_aor *aor, const char *uri
struct ast_sip_endpoint *endpoint);
/*!
+ * \brief Create a new contact for an AOR without locking the AOR
+ * \since 13.18.0
+ *
+ * \param aor Pointer to the AOR
+ * \param uri Full contact URI
+ * \param expiration_time Optional expiration time of the contact
+ * \param path_info Path information
+ * \param user_agent User-Agent header from REGISTER request
+ * \param via_addr
+ * \param via_port
+ * \param call_id
+ * \param prune_on_boot Non-zero if the contact cannot survive a restart/boot.
+ * \param endpoint The endpoint that resulted in the contact being added
+ *
+ * \return The created contact or NULL on failure.
+ *
+ * \warning
+ * This function should only be called if you already hold a named write lock on the aor.
+ */
+struct ast_sip_contact *ast_sip_location_create_contact(struct ast_sip_aor *aor,
+ const char *uri, struct timeval expiration_time, const char *path_info,
+ const char *user_agent, const char *via_addr, int via_port, const char *call_id,
+ int prune_on_boot, struct ast_sip_endpoint *endpoint);
+
+/*!
* \brief Update a contact
*
* \param contact New contact object with details
@@ -1168,6 +1322,12 @@ int ast_sip_location_update_contact(struct ast_sip_contact *contact);
int ast_sip_location_delete_contact(struct ast_sip_contact *contact);
/*!
+ * \brief Prune the prune_on_boot contacts
+ * \since 13.18.0
+ */
+void ast_sip_location_prune_boot_contacts(void);
+
+/*!
* \brief Callback called when an outbound request with authentication credentials is to be sent in dialog
*
* This callback will have the created request on it. The callback's purpose is to do any extra
@@ -1657,6 +1817,26 @@ pjsip_dialog *ast_sip_create_dialog_uas(const struct ast_sip_endpoint *endpoint,
/*!
* \brief General purpose method for creating an rdata structure using specific information
+ * \since 13.15.0
+ *
+ * \param rdata[out] The rdata structure that will be populated
+ * \param packet A SIP message
+ * \param src_name The source IP address of the message
+ * \param src_port The source port of the message
+ * \param transport_type The type of transport the message was received on
+ * \param local_name The local IP address the message was received on
+ * \param local_port The local port the message was received on
+ * \param contact_uri The contact URI of the message
+ *
+ * \retval 0 success
+ * \retval -1 failure
+ */
+int ast_sip_create_rdata_with_contact(pjsip_rx_data *rdata, char *packet,
+ const char *src_name, int src_port, char *transport_type, const char *local_name,
+ int local_port, const char *contact_uri);
+
+/*!
+ * \brief General purpose method for creating an rdata structure using specific information
*
* \param rdata[out] The rdata structure that will be populated
* \param packet A SIP message
@@ -1669,8 +1849,8 @@ pjsip_dialog *ast_sip_create_dialog_uas(const struct ast_sip_endpoint *endpoint,
* \retval 0 success
* \retval -1 failure
*/
-int ast_sip_create_rdata(pjsip_rx_data *rdata, char *packet, const char *src_name, int src_port, char *transport_type,
- const char *local_name, int local_port);
+int ast_sip_create_rdata(pjsip_rx_data *rdata, char *packet, const char *src_name,
+ int src_port, char *transport_type, const char *local_name, int local_port);
/*!
* \brief General purpose method for creating a SIP request
@@ -1949,6 +2129,24 @@ int ast_sip_append_body(pjsip_tx_data *tdata, const char *body_text);
void ast_copy_pj_str(char *dest, const pj_str_t *src, size_t size);
/*!
+ * \brief Create and copy a pj_str_t into a standard character buffer.
+ *
+ * pj_str_t is not NULL-terminated. Any place that expects a NULL-
+ * terminated string needs to have the pj_str_t copied into a separate
+ * buffer.
+ *
+ * Copies the pj_str_t contents into a newly allocated buffer pointed to
+ * by dest. NULL-terminates the buffer.
+ *
+ * \note Caller is responsible for freeing the allocated memory.
+ *
+ * \param dest [out] The destination buffer
+ * \param src The pj_str_t to copy
+ * \retval Number of characters copied or negative value on error
+ */
+int ast_copy_pj_str2(char **dest, const pj_str_t *src);
+
+/*!
* \brief Get the looked-up endpoint on an out-of dialog request or response
*
* The function may ONLY be called on out-of-dialog requests or responses. For
@@ -2423,14 +2621,20 @@ struct ast_sip_supplement {
* \retval 0 Success
* \retval -1 Failure
*/
-int ast_sip_register_supplement(struct ast_sip_supplement *supplement);
+#define ast_sip_register_supplement(supplement) \
+ __ast_sip_register_supplement(supplement, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+int __ast_sip_register_supplement(struct ast_sip_supplement *supplement,
+ const char *file, int line, const char *func);
/*!
* \brief Unregister a an supplement to SIP out of dialog processing
*
* \param supplement The supplement to unregister
*/
-void ast_sip_unregister_supplement(struct ast_sip_supplement *supplement);
+#define ast_sip_unregister_supplement(supplement) \
+ __ast_sip_unregister_supplement(supplement, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+void __ast_sip_unregister_supplement(struct ast_sip_supplement *supplement,
+ const char *file, int line, const char *func);
/*!
* \brief Retrieve the global MWI taskprocessor high water alert trigger level.
@@ -2707,4 +2911,168 @@ void ast_sip_modify_id_header(pj_pool_t *pool, pjsip_fromto_hdr *id_hdr,
void ast_sip_get_unidentified_request_thresholds(unsigned int *count, unsigned int *period,
unsigned int *prune_interval);
+/*!
+ * \brief Get the transport name from an endpoint or request uri
+ * \since 13.15.0
+ *
+ * \param endpoint
+ * \param sip_uri
+ * \param buf Buffer to receive transport name
+ * \param buf_len Buffer length
+ *
+ * \retval 0 Success
+ * \retval -1 Failure
+ *
+ * \note
+ * If endpoint->transport is not NULL, it is returned in buf.
+ * Otherwise if sip_uri has an 'x-ast-txp' parameter AND the sip_uri host is
+ * an ip4 or ip6 address, its value is returned,
+ */
+int ast_sip_get_transport_name(const struct ast_sip_endpoint *endpoint,
+ pjsip_sip_uri *sip_uri, char *buf, size_t buf_len);
+
+/*!
+ * \brief Sets pjsip_tpselector from an endpoint or uri
+ * \since 13.15.0
+ *
+ * \param endpoint If endpoint->transport is set, it's used
+ * \param sip_uri If sip_uri contains a x-ast-txp parameter, it's used
+ * \param selector The selector to be populated
+ *
+ * \retval 0 success
+ * \retval -1 failure
+ */
+int ast_sip_set_tpselector_from_ep_or_uri(const struct ast_sip_endpoint *endpoint,
+ pjsip_sip_uri *sip_uri, pjsip_tpselector *selector);
+
+/*!
+ * \brief Set the transport on a dialog
+ * \since 13.15.0
+ *
+ * \param endpoint
+ * \param dlg
+ * \param selector (optional)
+ *
+ * \note
+ * This API calls ast_sip_get_transport_name(endpoint, dlg->target) and if the result is
+ * non-NULL, calls pjsip_dlg_set_transport. If 'selector' is non-NULL, it is updated with
+ * the selector used.
+ */
+int ast_sip_dlg_set_transport(const struct ast_sip_endpoint *endpoint, pjsip_dialog *dlg,
+ pjsip_tpselector *selector);
+
+/*!
+ * \brief Convert the DTMF mode enum value into a string
+ * \since 13.18.0
+ *
+ * \param dtmf the dtmf mode
+ * \param buf Buffer to receive dtmf mode string
+ * \param buf_len Buffer length
+ *
+ * \retval 0 Success
+ * \retval -1 Failure
+ *
+ */
+int ast_sip_dtmf_to_str(const enum ast_sip_dtmf_mode dtmf,
+ char *buf, size_t buf_len);
+
+/*!
+ * \brief Convert the DTMF mode name into an enum
+ * \since 13.18.0
+ *
+ * \param dtmf_mode dtmf mode as a string
+ *
+ * \retval >= 0 The enum value
+ * \retval -1 Failure
+ *
+ */
+int ast_sip_str_to_dtmf(const char *dtmf_mode);
+
+/*!
+ * \brief Transport shutdown monitor callback.
+ * \since 13.18.0
+ *
+ * \param data User data to know what to do when transport shuts down.
+ *
+ * \note The callback does not need to care that data is an ao2 object.
+ *
+ * \return Nothing
+ */
+typedef void (*ast_transport_monitor_shutdown_cb)(void *data);
+
+enum ast_transport_monitor_reg {
+ /*! \brief Successfully registered the transport monitor */
+ AST_TRANSPORT_MONITOR_REG_SUCCESS,
+ /*! \brief Replaced the already existing transport monitor with new one. */
+ AST_TRANSPORT_MONITOR_REG_REPLACED,
+ /*!
+ * \brief Transport not found to monitor.
+ * \note Transport is either already shutdown or is not reliable.
+ */
+ AST_TRANSPORT_MONITOR_REG_NOT_FOUND,
+ /*! \brief Error while registering transport monitor. */
+ AST_TRANSPORT_MONITOR_REG_FAILED,
+};
+
+/*!
+ * \brief Register a reliable transport shutdown monitor callback.
+ * \since 13.18.0
+ *
+ * \param transport Transport to monitor for shutdown.
+ * \param cb Who to call when transport is shutdown.
+ * \param ao2_data Data to pass with the callback.
+ *
+ * \return enum ast_transport_monitor_reg
+ */
+enum ast_transport_monitor_reg ast_sip_transport_monitor_register(pjsip_transport *transport,
+ ast_transport_monitor_shutdown_cb cb, void *ao2_data);
+
+/*!
+ * \brief Unregister a reliable transport shutdown monitor callback.
+ * \since 13.18.0
+ *
+ * \param transport Transport to monitor for shutdown.
+ * \param cb Who to call when transport is shutdown.
+ *
+ * \return Nothing
+ */
+void ast_sip_transport_monitor_unregister(pjsip_transport *transport, ast_transport_monitor_shutdown_cb cb);
+
+/*!
+ * \brief Unregister monitor callback from all reliable transports.
+ * \since 13.18.0
+ *
+ * \param cb Who to call when a transport is shutdown.
+ *
+ * \return Nothing
+ */
+void ast_sip_transport_monitor_unregister_all(ast_transport_monitor_shutdown_cb cb);
+
+/*! Transport state notification registration element. */
+struct ast_sip_tpmgr_state_callback {
+ /*! PJPROJECT transport state notification callback */
+ pjsip_tp_state_callback cb;
+ AST_LIST_ENTRY(ast_sip_tpmgr_state_callback) node;
+};
+
+/*!
+ * \brief Register a transport state notification callback element.
+ * \since 13.18.0
+ *
+ * \param element What we are registering.
+ *
+ * \return Nothing
+ */
+void ast_sip_transport_state_register(struct ast_sip_tpmgr_state_callback *element);
+
+/*!
+ * \brief Unregister a transport state notification callback element.
+ * \since 13.18.0
+ *
+ * \param element What we are unregistering.
+ *
+ * \return Nothing
+ */
+void ast_sip_transport_state_unregister(struct ast_sip_tpmgr_state_callback *element);
+
#endif /* _RES_PJSIP_H */
diff --git a/include/asterisk/res_pjsip_presence_xml.h b/include/asterisk/res_pjsip_presence_xml.h
index deed0901e..55b79ad6e 100644
--- a/include/asterisk/res_pjsip_presence_xml.h
+++ b/include/asterisk/res_pjsip_presence_xml.h
@@ -69,7 +69,8 @@ void ast_sip_sanitize_xml(const char *input, char *output, size_t len);
* \param[out] local_state
*/
void ast_sip_presence_exten_state_to_str(int state, char **statestring,
- char **pidfstate, char **pidfnote, enum ast_sip_pidf_state *local_state);
+ char **pidfstate, char **pidfnote, enum ast_sip_pidf_state *local_state,
+ unsigned int notify_early_inuse_ringing);
/*!
* \brief Create XML attribute
diff --git a/include/asterisk/res_pjsip_session.h b/include/asterisk/res_pjsip_session.h
index 26dd451a7..a0fc9650e 100644
--- a/include/asterisk/res_pjsip_session.h
+++ b/include/asterisk/res_pjsip_session.h
@@ -28,6 +28,8 @@
#include "asterisk/netsock2.h"
/* Needed for ast_sdp_srtp struct */
#include "asterisk/sdp_srtp.h"
+/* Needed for ast_media_type */
+#include "asterisk/codec.h"
/* Forward declarations */
struct ast_sip_endpoint;
@@ -56,17 +58,21 @@ enum ast_sip_session_t38state {
};
struct ast_sip_session_sdp_handler;
+struct ast_sip_session;
+struct ast_sip_session_media;
+
+typedef struct ast_frame *(*ast_sip_session_media_read_cb)(struct ast_sip_session *session, struct ast_sip_session_media *session_media);
+typedef int (*ast_sip_session_media_write_cb)(struct ast_sip_session *session, struct ast_sip_session_media *session_media,
+ struct ast_frame *frame);
/*!
* \brief A structure containing SIP session media information
*/
struct ast_sip_session_media {
- union {
- /*! \brief RTP instance itself */
- struct ast_rtp_instance *rtp;
- /*! \brief UDPTL instance itself */
- struct ast_udptl *udptl;
- };
+ /*! \brief RTP instance itself */
+ struct ast_rtp_instance *rtp;
+ /*! \brief UDPTL instance itself */
+ struct ast_udptl *udptl;
/*! \brief Direct media address */
struct ast_sockaddr direct_media_addr;
/*! \brief SDP handler that setup the RTP */
@@ -85,8 +91,54 @@ struct ast_sip_session_media {
unsigned int remotely_held:1;
/*! \brief Stream is on hold by local side */
unsigned int locally_held:1;
- /*! \brief Stream type this session media handles */
- char stream_type[1];
+ /*! \brief Does remote support rtcp_mux */
+ unsigned int remote_rtcp_mux:1;
+ /*! \brief Media type of this session media */
+ enum ast_media_type type;
+ /*! \brief The write callback when writing frames */
+ ast_sip_session_media_write_cb write_callback;
+ /*! \brief The stream number to place into any resulting frames */
+ int stream_num;
+ /*! \brief Media identifier for this stream (may be shared across multiple streams) */
+ char *mid;
+ /*! \brief The bundle group the stream belongs to */
+ int bundle_group;
+ /*! \brief Whether this stream is currently bundled or not */
+ unsigned int bundled;
+ /*! \brief Media stream label */
+ char mslabel[AST_UUID_STR_LEN];
+ /*! \brief Track label */
+ char label[AST_UUID_STR_LEN];
+ /*! \brief The underlying session has been changed in some fashion */
+ unsigned int changed;
+ /*! \brief Remote media stream label */
+ char *remote_mslabel;
+};
+
+/*!
+ * \brief Structure which contains read callback information
+ */
+struct ast_sip_session_media_read_callback_state {
+ /*! \brief The file descriptor itself */
+ int fd;
+ /*! \brief The callback to invoke */
+ ast_sip_session_media_read_cb read_callback;
+ /*! \brief The media session */
+ struct ast_sip_session_media *session;
+};
+
+/*!
+ * \brief Structure which contains media state information (streams, sessions)
+ */
+struct ast_sip_session_media_state {
+ /*! \brief Mapping of stream to media sessions */
+ AST_VECTOR(, struct ast_sip_session_media *) sessions;
+ /*! \brief Added read callbacks - these are whole structs and not pointers */
+ AST_VECTOR(, struct ast_sip_session_media_read_callback_state) read_callbacks;
+ /*! \brief Default media sessions for each type */
+ struct ast_sip_session_media *default_session[AST_MEDIA_TYPE_END];
+ /*! \brief The media stream topology */
+ struct ast_stream_topology *topology;
};
/*!
@@ -121,8 +173,6 @@ struct ast_sip_session {
AST_LIST_HEAD(, ast_sip_session_supplement) supplements;
/*! Datastores added to the session by supplements to the session */
struct ao2_container *datastores;
- /*! Media streams */
- struct ao2_container *media;
/*! Serializer for tasks relating to this SIP session */
struct ast_taskprocessor *serializer;
/*! Non-null if the session serializer is suspended or being suspended. */
@@ -137,8 +187,10 @@ struct ast_sip_session {
pj_timer_entry scheduled_termination;
/*! Identity of endpoint this session deals with */
struct ast_party_id id;
- /*! Requested capabilities */
- struct ast_format_cap *req_caps;
+ /*! Active media state (sessions + streams) - contents are guaranteed not to change */
+ struct ast_sip_session_media_state *active_media_state;
+ /*! Pending media state (sessions + streams) */
+ struct ast_sip_session_media_state *pending_media_state;
/*! Optional DSP, used only for inband DTMF/Fax-CNG detection if configured */
struct ast_dsp *dsp;
/*! Whether the termination of the session should be deferred */
@@ -153,6 +205,12 @@ struct ast_sip_session {
struct ast_sip_aor *aor;
/*! From header saved at invite creation */
pjsip_fromto_hdr *saved_from_hdr;
+ /*! Whether the end of the session should be deferred */
+ unsigned int defer_end:1;
+ /*! Session end (remote hangup) requested while termination deferred */
+ unsigned int ended_while_deferred:1;
+ /*! DTMF mode to use with this session, from endpoint but can change */
+ enum ast_sip_dtmf_mode dtmf;
};
typedef int (*ast_sip_session_request_creation_cb)(struct ast_sip_session *session, pjsip_tx_data *tdata);
@@ -309,34 +367,29 @@ struct ast_sip_session_sdp_handler {
/*!
* \brief Set session details based on a stream in an incoming SDP offer or answer
* \param session The session for which the media is being negotiated
- * \param session_media The media to be setup for this session
+ * \param session_media The media session
* \param sdp The entire SDP. Useful for getting "global" information, such as connections or attributes
- * \param stream The stream on which to operate
- * \retval 0 The stream was not handled by this handler. If there are other registered handlers for this stream type, they will be called.
- * \retval <0 There was an error encountered. No further operation will take place and the current negotiation will be abandoned.
- * \retval >0 The stream was handled by this handler. No further handler of this stream type will be called.
- */
- int (*negotiate_incoming_sdp_stream)(struct ast_sip_session *session, struct ast_sip_session_media *session_media, const struct pjmedia_sdp_session *sdp, const struct pjmedia_sdp_media *stream);
- /*!
- * \brief Create an SDP media stream and add it to the outgoing SDP offer or answer
- * \param session The session for which media is being added
- * \param session_media The media to be setup for this session
- * \param stream The stream on which to operate
+ * \param index The index for the session media, Asterisk stream, and PJMEDIA stream being negotiated
+ * \param asterisk_stream The Asterisk stream representation
* \retval 0 The stream was not handled by this handler. If there are other registered handlers for this stream type, they will be called.
* \retval <0 There was an error encountered. No further operation will take place and the current negotiation will be abandoned.
* \retval >0 The stream was handled by this handler. No further handler of this stream type will be called.
*/
- int (*handle_incoming_sdp_stream)(struct ast_sip_session *session, struct ast_sip_session_media *session_media, const struct pjmedia_sdp_session *sdp, struct pjmedia_sdp_media *stream);
+ int (*negotiate_incoming_sdp_stream)(struct ast_sip_session *session, struct ast_sip_session_media *session_media,
+ const struct pjmedia_sdp_session *sdp, int index, struct ast_stream *asterisk_stream);
/*!
* \brief Create an SDP media stream and add it to the outgoing SDP offer or answer
* \param session The session for which media is being added
* \param session_media The media to be setup for this session
* \param sdp The entire SDP as currently built
+ * \param remote Optional remote SDP if this is an answer
+ * \param stream The stream that is to be added to the outgoing SDP
* \retval 0 This handler has no stream to add. If there are other registered handlers for this stream type, they will be called.
* \retval <0 There was an error encountered. No further operation will take place and the current SDP negotiation will be abandoned.
* \retval >0 The handler has a stream to be added to the SDP. No further handler of this stream type will be called.
*/
- int (*create_outgoing_sdp_stream)(struct ast_sip_session *session, struct ast_sip_session_media *session_media, struct pjmedia_sdp_session *sdp);
+ int (*create_outgoing_sdp_stream)(struct ast_sip_session *session, struct ast_sip_session_media *session_media, struct pjmedia_sdp_session *sdp,
+ const struct pjmedia_sdp_session *remote, struct ast_stream *stream);
/*!
* \brief Update media stream with external address if applicable
* \param tdata The outgoing message itself
@@ -347,17 +400,18 @@ struct ast_sip_session_sdp_handler {
/*!
* \brief Apply a negotiated SDP media stream
* \param session The session for which media is being applied
- * \param session_media The media to be setup for this session
+ * \param session_media The media session
* \param local The entire local negotiated SDP
- * \param local_stream The local stream which to apply
* \param remote The entire remote negotiated SDP
- * \param remote_stream The remote stream which to apply
+ * \param index The index of the session media, SDP streams, and Asterisk streams
+ * \param asterisk_stream The Asterisk stream representation
* \retval 0 The stream was not applied by this handler. If there are other registered handlers for this stream type, they will be called.
* \retval <0 There was an error encountered. No further operation will take place and the current application will be abandoned.
* \retval >0 The stream was handled by this handler. No further handler of this stream type will be called.
*/
- int (*apply_negotiated_sdp_stream)(struct ast_sip_session *session, struct ast_sip_session_media *session_media, const struct pjmedia_sdp_session *local, const struct pjmedia_sdp_media *local_stream,
- const struct pjmedia_sdp_session *remote, const struct pjmedia_sdp_media *remote_stream);
+ int (*apply_negotiated_sdp_stream)(struct ast_sip_session *session, struct ast_sip_session_media *session_media,
+ const struct pjmedia_sdp_session *local, const struct pjmedia_sdp_session *remote, int index,
+ struct ast_stream *asterisk_stream);
/*!
* \brief Stop a session_media created by this handler but do not destroy resources
* \param session The session for which media is being stopped
@@ -387,7 +441,7 @@ struct ast_sip_channel_pvt {
/*!
* \brief Allocate a new SIP channel pvt structure
*
- * \param pvt Pointer to channel specific implementation
+ * \param pvt Pointer to channel specific information
* \param session Pointer to SIP session
*
* \retval non-NULL success
@@ -446,17 +500,21 @@ void ast_sip_session_unsuspend(struct ast_sip_session *session);
* \param contact The contact that this session will communicate with
* \param location Name of the location to call, be it named location or explicit URI. Overrides contact if present.
* \param request_user Optional request user to place in the request URI if permitted
- * \param req_caps The requested capabilities
+ * \param req_topology The requested capabilities
*/
struct ast_sip_session *ast_sip_session_create_outgoing(struct ast_sip_endpoint *endpoint,
struct ast_sip_contact *contact, const char *location, const char *request_user,
- struct ast_format_cap *req_caps);
+ struct ast_stream_topology *req_topology);
/*!
* \brief Terminate a session and, if possible, send the provided response code
*
* \param session The session to terminate
* \param response The response code to use for termination if possible
+ *
+ * \warning Calling this function MAY cause the last session reference to be
+ * released and the session destructor to be called. If you need to do something
+ * with session after this call, be sure to bump the ref count before calling terminate.
*/
void ast_sip_session_terminate(struct ast_sip_session *session, int response);
@@ -478,6 +536,13 @@ int ast_sip_session_defer_termination(struct ast_sip_session *session);
void ast_sip_session_defer_termination_cancel(struct ast_sip_session *session);
/*!
+ * \brief End the session if it had been previously deferred
+ *
+ * \param session The session to end if it had been deferred
+ */
+void ast_sip_session_end_if_deferred(struct ast_sip_session *session);
+
+/*!
* \brief Register an SDP handler
*
* An SDP handler is responsible for parsing incoming SDP streams and ensuring that
@@ -515,14 +580,27 @@ void ast_sip_session_unregister_sdp_handler(struct ast_sip_session_sdp_handler *
* \retval 0 Success
* \retval -1 Failure
*/
-int ast_sip_session_register_supplement(struct ast_sip_session_supplement *supplement);
+#define ast_sip_session_register_supplement(supplement) \
+ __ast_sip_session_register_supplement(supplement, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+int __ast_sip_session_register_supplement(struct ast_sip_session_supplement *supplement,
+ const char *file, int line, const char *func);
/*!
* \brief Unregister a an supplement to SIP session processing
*
* \param supplement The supplement to unregister
*/
-void ast_sip_session_unregister_supplement(struct ast_sip_session_supplement *supplement);
+#define ast_sip_session_unregister_supplement(supplement) \
+ __ast_sip_session_unregister_supplement(supplement, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+void __ast_sip_session_unregister_supplement(struct ast_sip_session_supplement *supplement,
+ const char *file, int line, const char *func);
+
+/*!
+ * \brief Add supplements to a SIP session
+ *
+ * \param session The session to initialize
+ */
+int ast_sip_session_add_supplements(struct ast_sip_session *session);
/*!
* \brief Alternative for ast_datastore_alloc()
@@ -596,15 +674,37 @@ void ast_sip_session_remove_datastore(struct ast_sip_session *session, const cha
* \param on_response Callback called when response for request is received
* \param method The method that should be used when constructing the session refresh
* \param generate_new_sdp Boolean to indicate if a new SDP should be created
+ * \param media_state Optional requested media state for the SDP
+ *
* \retval 0 Successfully sent refresh
* \retval -1 Failure to send refresh
+ *
+ * \note If a media_state is passed in ownership will be taken in all cases
*/
int ast_sip_session_refresh(struct ast_sip_session *session,
ast_sip_session_request_creation_cb on_request_creation,
ast_sip_session_sdp_creation_cb on_sdp_creation,
ast_sip_session_response_cb on_response,
enum ast_sip_session_refresh_method method,
- int generate_new_sdp);
+ int generate_new_sdp,
+ struct ast_sip_session_media_state *media_state);
+
+/*!
+ * \brief Regenerate SDP Answer
+ *
+ * This method is used when an SDP offer has been received but an SDP answer
+ * has not been sent yet. It requests that a new local SDP be created and
+ * set as the SDP answer. As with any outgoing request in res_pjsip_session,
+ * this will call into registered supplements in case they wish to add anything.
+ *
+ * \param session The session on which the answer will be updated
+ * \param on_sdp_creation Callback called when SDP is created
+ * \param generate_new_sdp Boolean to indicate if a new SDP should be created
+ * \retval 0 Successfully updated the SDP answer
+ * \retval -1 Failure to updated the SDP answer
+ */
+int ast_sip_session_regenerate_answer(struct ast_sip_session *session,
+ ast_sip_session_sdp_creation_cb on_sdp_creation);
/*!
* \brief Send a SIP response
@@ -675,6 +775,123 @@ struct ast_sip_session *ast_sip_dialog_get_session(pjsip_dialog *dlg);
*/
void ast_sip_session_resume_reinvite(struct ast_sip_session *session);
+/*!
+ * \brief Determines if a provided pending stream will be the default stream or not
+ * \since 15.0.0
+ *
+ * \param session The session to check against
+ * \param stream The pending stream
+ *
+ * \retval 1 if stream will be default
+ * \retval 0 if stream will NOT be the default
+ */
+int ast_sip_session_is_pending_stream_default(const struct ast_sip_session *session, const struct ast_stream *stream);
+
+/*!
+ * \brief Allocate a session media state structure
+ * \since 15.0.0
+ *
+ * \retval non-NULL success
+ * \retval NULL failure
+ */
+struct ast_sip_session_media_state *ast_sip_session_media_state_alloc(void);
+
+/*!
+ * \brief Allocate an ast_session_media and add it to the media state's vector.
+ * \since 15.0.0
+ *
+ * This allocates a session media of the specified type. The position argument
+ * determines where in the vector that the new session media will be inserted.
+ *
+ * \note The returned ast_session_media is the reference held by the vector. Callers
+ * of this function must NOT decrement the refcount of the session media.
+ *
+ * \param session Session on which to query active media state for
+ * \param media_state Media state to place the session media into
+ * \param type The type of the session media
+ * \param position Position at which to insert the new session media.
+ *
+ * \note The active media state will be queried and if a media session already
+ * exists at the given position for the same type it will be reused instead of
+ * allocating a new one.
+ *
+ * \retval non-NULL success
+ * \retval NULL failure
+ */
+struct ast_sip_session_media *ast_sip_session_media_state_add(struct ast_sip_session *session,
+ struct ast_sip_session_media_state *media_state, enum ast_media_type type, int position);
+
+/*!
+ * \brief Reset a media state to a clean state
+ * \since 15.0.0
+ *
+ * \param media_state The media state to reset
+ */
+void ast_sip_session_media_state_reset(struct ast_sip_session_media_state *media_state);
+
+/*!
+ * \brief Clone a media state
+ * \since 15.0.0
+ *
+ * \param media_state The media state to clone
+ *
+ * \retval non-NULL success
+ * \retval NULL failure
+ */
+struct ast_sip_session_media_state *ast_sip_session_media_state_clone(const struct ast_sip_session_media_state *media_state);
+
+/*!
+ * \brief Free a session media state structure
+ * \since 15.0.0
+ */
+void ast_sip_session_media_state_free(struct ast_sip_session_media_state *media_state);
+
+/*!
+ * \brief Set a read callback for a media session with a specific file descriptor
+ * \since 15.0.0
+ *
+ * \param session The session
+ * \param session_media The media session
+ * \param fd The file descriptor
+ * \param callback The read callback
+ *
+ * \retval 0 the read callback was successfully added
+ * \retval -1 the read callback could not be added
+ *
+ * \note This operations on the pending media state
+ */
+int ast_sip_session_media_add_read_callback(struct ast_sip_session *session, struct ast_sip_session_media *session_media,
+ int fd, ast_sip_session_media_read_cb callback);
+
+/*!
+ * \brief Set a write callback for a media session
+ * \since 15.0.0
+ *
+ * \param session The session
+ * \param session_media The media session
+ * \param callback The write callback
+ *
+ * \retval 0 the write callback was successfully add
+ * \retval -1 the write callback is already set to something different
+ *
+ * \note This operates on the pending media state
+ */
+int ast_sip_session_media_set_write_callback(struct ast_sip_session *session, struct ast_sip_session_media *session_media,
+ ast_sip_session_media_write_cb callback);
+
+/*!
+ * \brief Retrieve the underlying media session that is acting as transport for a media session
+ * \since 15.0.0
+ *
+ * \param session The session
+ * \param session_media The media session to retrieve the transport for
+ *
+ * \note This operates on the pending media state
+ *
+ * \note This function is guaranteed to return non-NULL
+ */
+struct ast_sip_session_media *ast_sip_session_media_get_transport(struct ast_sip_session *session, struct ast_sip_session_media *session_media);
+
/*! \brief Determines whether the res_pjsip_session module is loaded */
#define CHECK_PJSIP_SESSION_MODULE_LOADED() \
do { \
diff --git a/include/asterisk/rtp_engine.h b/include/asterisk/rtp_engine.h
index c0ae33155..f9d686aca 100644
--- a/include/asterisk/rtp_engine.h
+++ b/include/asterisk/rtp_engine.h
@@ -81,6 +81,12 @@ extern "C" {
/*! Maximum number of payload types RTP can support. */
#define AST_RTP_MAX_PT 128
+/*!
+ * Last RTP payload type statically assigned, see
+ * http://www.iana.org/assignments/rtp-parameters
+ */
+#define AST_RTP_PT_LAST_STATIC 34
+
/*! First dynamic RTP payload type */
#define AST_RTP_PT_FIRST_DYNAMIC 96
@@ -114,6 +120,8 @@ enum ast_rtp_property {
AST_RTP_PROPERTY_STUN,
/*! Enable RTCP support */
AST_RTP_PROPERTY_RTCP,
+ /*! Enable Asymmetric RTP Codecs */
+ AST_RTP_PROPERTY_ASYMMETRIC_CODEC,
/*!
* \brief Maximum number of RTP properties supported
@@ -237,6 +245,15 @@ enum ast_rtp_instance_stat {
AST_RTP_INSTANCE_STAT_RXOCTETCOUNT,
};
+enum ast_rtp_instance_rtcp {
+ /*! RTCP should not be sent/received */
+ AST_RTP_INSTANCE_RTCP_DISABLED = 0,
+ /*! RTCP should be sent/received based on standard port rules */
+ AST_RTP_INSTANCE_RTCP_STANDARD,
+ /*! RTCP should be sent/received on the same port as RTP */
+ AST_RTP_INSTANCE_RTCP_MUX,
+};
+
/* Codes for RTP-specific data - not defined by our AST_FORMAT codes */
/*! DTMF (RFC2833) */
#define AST_RTP_DTMF (1 << 0)
@@ -447,6 +464,8 @@ struct ast_rtp_engine_ice {
void (*turn_request)(struct ast_rtp_instance *instance, enum ast_rtp_ice_component_type component,
enum ast_transport transport, const char *server, unsigned int port,
const char *username, const char *password);
+ /*! Callback to alter the number of ICE components on a session */
+ void (*change_components)(struct ast_rtp_instance *instance, int num_components);
};
/*! \brief DTLS setup types */
@@ -489,6 +508,7 @@ struct ast_rtp_dtls_cfg {
char *cipher; /*!< Cipher to use */
char *cafile; /*!< Certificate authority file */
char *capath; /*!< Path to certificate authority */
+ unsigned int ephemeral_cert:1; /*!< Whether to not to generate an ephemeral certificate - defaults to 0 (off) */
};
/*! \brief Structure that represents the optional DTLS SRTP support within an RTP engine */
@@ -582,6 +602,16 @@ struct ast_rtp_engine {
void (*available_formats)(struct ast_rtp_instance *instance, struct ast_format_cap *to_endpoint, struct ast_format_cap *to_asterisk, struct ast_format_cap *result);
/*! Callback to send CNG */
int (*sendcng)(struct ast_rtp_instance *instance, int level);
+ /*! Callback to retrieve local SSRC */
+ unsigned int (*ssrc_get)(struct ast_rtp_instance *instance);
+ /*! Callback to retrieve RTCP SDES CNAME */
+ const char *(*cname_get)(struct ast_rtp_instance *instance);
+ /*! Callback to bundle an RTP instance to another */
+ int (*bundle)(struct ast_rtp_instance *child, struct ast_rtp_instance *parent);
+ /*! Callback to set remote SSRC information */
+ void (*set_remote_ssrc)(struct ast_rtp_instance *instance, unsigned int ssrc);
+ /*! Callback to set the stream identifier */
+ void (*set_stream_num)(struct ast_rtp_instance *instance, int stream_num);
/*! Callback to pointer for optional ICE support */
struct ast_rtp_engine_ice *ice;
/*! Callback to pointer for optional DTLS SRTP support */
@@ -619,12 +649,13 @@ struct ast_rtp_glue {
/*!
* \brief Used to prevent two channels from remotely bridging audio rtp if the channel tech has a
* reason for prohibiting it based on qualities that need to be compared from both channels.
- * \note This function may be NULL for a given channel driver. This should be accounted for and if that is the case, function this is not used.
+ * \note This function may be NULL for a given channel driver. This should be accounted for and if that is the case, this function is not used.
*/
int (*allow_rtp_remote)(struct ast_channel *chan1, struct ast_rtp_instance *instance);
/*!
* \brief Callback for retrieving the RTP instance carrying video
* \note This function increases the reference count on the returned RTP instance.
+ * \note This function may be NULL for a given channel driver. This should be accounted for and if that is the case, this function is not used.
*/
enum ast_rtp_glue_result (*get_vrtp_info)(struct ast_channel *chan, struct ast_rtp_instance **instance);
/*!
@@ -637,11 +668,15 @@ struct ast_rtp_glue {
/*!
* \brief Callback for retrieving the RTP instance carrying text
* \note This function increases the reference count on the returned RTP instance.
+ * \note This function may be NULL for a given channel driver. This should be accounted for and if that is the case, this function is not used.
*/
enum ast_rtp_glue_result (*get_trtp_info)(struct ast_channel *chan, struct ast_rtp_instance **instance);
/*! Callback for updating the destination that the remote side should send RTP to */
int (*update_peer)(struct ast_channel *chan, struct ast_rtp_instance *instance, struct ast_rtp_instance *vinstance, struct ast_rtp_instance *tinstance, const struct ast_format_cap *cap, int nat_active);
- /*! Callback for retrieving codecs that the channel can do. Result returned in result_cap. */
+ /*!
+ * \brief Callback for retrieving codecs that the channel can do. Result returned in result_cap.
+ * \note This function may be NULL for a given channel driver. This should be accounted for and if that is the case, this function is not used.
+ */
void (*get_codec)(struct ast_channel *chan, struct ast_format_cap *result_cap);
/*! Linked list information */
AST_RWLIST_ENTRY(ast_rtp_glue) entry;
@@ -1432,7 +1467,8 @@ unsigned int ast_rtp_codecs_get_framing(struct ast_rtp_codecs *codecs);
*
* \since 1.8
*/
-unsigned int ast_rtp_lookup_sample_rate2(int asterisk_format, struct ast_format *format, int code);
+unsigned int ast_rtp_lookup_sample_rate2(int asterisk_format,
+ const struct ast_format *format, int code);
/*!
* \brief Retrieve all formats that were found
@@ -1485,6 +1521,20 @@ void ast_rtp_codecs_payload_formats(struct ast_rtp_codecs *codecs, struct ast_fo
int ast_rtp_codecs_payload_code(struct ast_rtp_codecs *codecs, int asterisk_format, struct ast_format *format, int code);
/*!
+ * \brief Set a payload code for use with a specific Asterisk format
+ *
+ * \param codecs Codecs structure to manipulate
+ * \param code The payload code
+ * \param format Asterisk format
+ *
+ * \retval 0 Payload was set to the given format
+ * \retval -1 Payload was in use or could not be set
+ *
+ * \since 15.0.0
+ */
+int ast_rtp_codecs_payload_set_rx(struct ast_rtp_codecs *codecs, int code, struct ast_format *format);
+
+/*!
* \brief Retrieve a tx mapped payload type based on whether it is an Asterisk format and the code
* \since 14.0.0
*
@@ -1537,7 +1587,8 @@ int ast_rtp_codecs_find_payload_code(struct ast_rtp_codecs *codecs, int payload)
*
* \since 1.8
*/
-const char *ast_rtp_lookup_mime_subtype2(const int asterisk_format, struct ast_format *format, int code, enum ast_rtp_options options);
+const char *ast_rtp_lookup_mime_subtype2(const int asterisk_format,
+ const struct ast_format *format, int code, enum ast_rtp_options options);
/*!
* \brief Convert formats into a string and put them into a buffer
@@ -2243,6 +2294,8 @@ int ast_rtp_instance_sendcng(struct ast_rtp_instance *instance, int level);
*
* \retval 0 Success
* \retval non-zero Failure
+ *
+ * \note If no remote policy is provided any existing SRTP policies are left and the new local policy is added
*/
int ast_rtp_instance_add_srtp_policy(struct ast_rtp_instance *instance, struct ast_srtp_policy* remote_policy, struct ast_srtp_policy *local_policy, int rtcp);
@@ -2298,6 +2351,16 @@ struct ast_rtp_engine_dtls *ast_rtp_instance_get_dtls(struct ast_rtp_instance *i
int ast_rtp_dtls_cfg_parse(struct ast_rtp_dtls_cfg *dtls_cfg, const char *name, const char *value);
/*!
+ * \brief Validates DTLS related configuration options
+ *
+ * \param dtls_cfg a DTLS configuration structure
+ *
+ * \retval 0 if valid
+ * \retval -1 if invalid
+ */
+int ast_rtp_dtls_cfg_validate(struct ast_rtp_dtls_cfg *dtls_cfg);
+
+/*!
* \brief Copy contents of a DTLS configuration structure
*
* \param src_cfg source DTLS configuration structure
@@ -2370,6 +2433,54 @@ time_t ast_rtp_instance_get_last_rx(const struct ast_rtp_instance *rtp);
*/
void ast_rtp_instance_set_last_rx(struct ast_rtp_instance *rtp, time_t time);
+/*!
+ * \brief Retrieve the local SSRC value that we will be using
+ *
+ * \param rtp The RTP instance
+ * \return The SSRC value
+ */
+unsigned int ast_rtp_instance_get_ssrc(struct ast_rtp_instance *rtp);
+
+/*!
+ * \brief Retrieve the CNAME used in RTCP SDES items
+ *
+ * This is a pointer directly into the RTP struct, not a copy.
+ *
+ * \param rtp The RTP instance
+ * \return the CNAME
+ */
+const char *ast_rtp_instance_get_cname(struct ast_rtp_instance *rtp);
+
+/*!
+ * \brief Request that an RTP instance be bundled with another
+ * \since 15.0.0
+ *
+ * \param child The child RTP instance
+ * \param parent The parent RTP instance the child should be bundled with
+ *
+ * \retval 0 success
+ * \retval -1 failure
+ */
+int ast_rtp_instance_bundle(struct ast_rtp_instance *child, struct ast_rtp_instance *parent);
+
+/*!
+ * \brief Set the remote SSRC for an RTP instance
+ * \since 15.0.0
+ *
+ * \param rtp The RTP instance
+ * \param ssrc The remote SSRC
+ */
+void ast_rtp_instance_set_remote_ssrc(struct ast_rtp_instance *rtp, unsigned int ssrc);
+
+/*!
+ * \brief Set the stream number for an RTP instance
+ * \since 15.0.0
+ *
+ * \param rtp The RTP instance
+ * \param stream_num The stream identifier number
+ */
+void ast_rtp_instance_set_stream_num(struct ast_rtp_instance *instance, int stream_num);
+
/*! \addtogroup StasisTopicsAndMessages
* @{
*/
diff --git a/include/asterisk/sdp.h b/include/asterisk/sdp.h
new file mode 100644
index 000000000..768469544
--- /dev/null
+++ b/include/asterisk/sdp.h
@@ -0,0 +1,703 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2017, 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.
+ */
+
+/* NOTE: It is unlikely that you need to include this file. You probably will only need
+ * this if you are an SDP translator, or if you are an inner part of the SDP API
+ */
+
+#ifndef _SDP_PRIV_H
+#define _SDP_PRIV_H
+
+#include "asterisk/vector.h"
+#include "asterisk/format.h"
+#include "asterisk/sdp_state.h"
+#include "asterisk/stream.h"
+
+/*!
+ * \brief Structure representing an SDP Attribute
+ */
+struct ast_sdp_a_line {
+ /*! Attribute name */
+ char *name;
+ /*! Attribute value. For attributes that have no value, this will be an empty string */
+ char *value;
+};
+
+/*!
+ * \brief A collection of SDP Attributes
+ */
+AST_VECTOR(ast_sdp_a_lines, struct ast_sdp_a_line *);
+
+/*!
+ * \brief Structure representing an SDP Connection
+ */
+struct ast_sdp_c_line {
+ /* IP family string (e.g. IP4 or IP6) */
+ char *address_type;
+ /* Connection address. Can be an IP address or FQDN */
+ char *address;
+};
+
+/*!
+ * \brief Structre representing SDP Media Payloads
+ */
+struct ast_sdp_payload {
+ /* Media format description */
+ char *fmt;
+};
+
+/*!
+ * \brief A collection of SDP Media Payloads
+ */
+AST_VECTOR(ast_sdp_payloads, struct ast_sdp_payload *);
+
+/*!
+ * \brief Structure representing an SDP Media Stream
+ *
+ * This contains both the m line, as well as its
+ * constituent a lines.
+ */
+struct ast_sdp_m_line {
+ /*! Media type (e.g. "audio" or "video") */
+ char *type;
+ /*! RTP profile string (e.g. "RTP/AVP") */
+ char *proto;
+ /*! Port number in m line */
+ uint16_t port;
+ /*! Number of ports specified in m line */
+ uint16_t port_count;
+ /*! RTP payloads */
+ struct ast_sdp_payloads *payloads;
+ /*! Connection information for this media stream */
+ struct ast_sdp_c_line *c_line;
+ /*! The attributes for this media stream */
+ struct ast_sdp_a_lines *a_lines;
+};
+
+/*!
+ * \brief A collection of SDP Media Streams
+ */
+AST_VECTOR(ast_sdp_m_lines, struct ast_sdp_m_line *);
+
+/*!
+ * \brief Structure representing an SDP Origin
+ */
+struct ast_sdp_o_line {
+ /*! Origin user name */
+ char *username;
+ /*! Origin id */
+ uint64_t session_id;
+ /*! Origin version */
+ uint64_t session_version;
+ /*! Origin IP address type (e.g. "IP4" or "IP6") */
+ char *address_type;
+ /*! Origin address. Can be an IP address or FQDN */
+ char *address;
+};
+
+/*!
+ * \brief Structure representing an SDP Session Name
+ */
+struct ast_sdp_s_line {
+ /* Session Name */
+ char *session_name;
+};
+
+/*!
+ * \brief Structure representing SDP Timing
+ */
+struct ast_sdp_t_line {
+ /*! Session start time */
+ uint64_t start_time;
+ /*! Session end time */
+ uint64_t stop_time;
+};
+
+/*!
+ * \brief An SDP
+ */
+struct ast_sdp {
+ /*! SDP Origin line */
+ struct ast_sdp_o_line *o_line;
+ /*! SDP Session name */
+ struct ast_sdp_s_line *s_line;
+ /*! SDP top-level connection information */
+ struct ast_sdp_c_line *c_line;
+ /*! SDP timing information */
+ struct ast_sdp_t_line *t_line;
+ /*! SDP top-level attributes */
+ struct ast_sdp_a_lines *a_lines;
+ /*! SDP media streams */
+ struct ast_sdp_m_lines *m_lines;
+};
+
+/*!
+ * \brief A structure representing an SDP rtpmap attribute
+ */
+struct ast_sdp_rtpmap {
+ /*! The RTP payload number for the rtpmap */
+ int payload;
+ /*! The Name of the codec */
+ char *encoding_name;
+ /*! The clock rate of the codec */
+ int clock_rate;
+ /*! Optional encoding parameters */
+ char *encoding_parameters;
+ /*! Area where strings are stored */
+ char buf[0];
+};
+
+/*!
+ * \brief Free an SDP Attribute
+ *
+ * \param a_line The attribute to free
+ *
+ * \since 15
+ */
+void ast_sdp_a_free(struct ast_sdp_a_line *a_line);
+
+/*!
+ * \brief Free an SDP Attribute collection
+ *
+ * \param a_lines The attribute collection to free
+ *
+ * \since 15
+ */
+void ast_sdp_a_lines_free(struct ast_sdp_a_lines *a_lines);
+
+/*!
+ * \brief Free SDP Connection Data
+ *
+ * \param c_line The connection data to free
+ *
+ * \since 15
+ */
+void ast_sdp_c_free(struct ast_sdp_c_line *c_line);
+
+/*!
+ * \brief Free an SDP Media Description Payload
+ *
+ * \param payload The payload to free
+ *
+ * \since 15
+ */
+void ast_sdp_payload_free(struct ast_sdp_payload *payload);
+
+/*!
+ * \brief Free an SDP Media Description Payload collection
+ *
+ * \param payloads collection to free
+ *
+ * \since 15
+ */
+void ast_sdp_payloads_free(struct ast_sdp_payloads *payloads);
+
+/*!
+ * \brief Free an SDP Media Description
+ * Frees the media description and all resources it contains
+ *
+ * \param m_line The media description to free
+ *
+ * \since 15
+ */
+void ast_sdp_m_free(struct ast_sdp_m_line *m_line);
+
+/*!
+ * \brief Free an SDP Media Description collection
+ *
+ * \param m_lines The collection description to free
+ *
+ * \since 15
+ */
+void ast_sdp_m_lines_free(struct ast_sdp_m_lines *m_lines);
+
+/*!
+ * \brief Free an SDP Origin
+ *
+ * \param o_line The origin description to free
+ *
+ * \since 15
+ */
+void ast_sdp_o_free(struct ast_sdp_o_line *o_line);
+
+/*!
+ * \brief Free an SDP Session
+ *
+ * \param s_line The session to free
+ *
+ * \since 15
+ */
+void ast_sdp_s_free(struct ast_sdp_s_line *s_line);
+
+/*!
+ * \brief Free SDP Timing
+ *
+ * \param t_line The timing description to free
+ *
+ * \since 15
+ */
+void ast_sdp_t_free(struct ast_sdp_t_line *t_line);
+
+/*!
+ * \brief Allocate an SDP Attribute
+ *
+ * \param name Attribute Name
+ * \param value Attribute Name
+ *
+ * \retval non-NULL Success
+ * \retval NULL Failure
+ *
+ * \since 15
+ */
+struct ast_sdp_a_line *ast_sdp_a_alloc(const char *name, const char *value);
+
+/*!
+ * \brief Allocate an SDP Connection
+ *
+ * \param family Family ("IN", etc)
+ * \param addr Address
+ *
+ * \retval non-NULL Success
+ * \retval NULL Failure
+ *
+ * \since 15
+ */
+struct ast_sdp_c_line *ast_sdp_c_alloc(const char *family, const char *addr);
+
+/*!
+ * \brief Allocate an SDP Media Description Payload
+ *
+ * \param fmt The media format description
+ *
+ * \retval non-NULL Success
+ * \retval NULL Failure
+ *
+ * \since 15
+ */
+struct ast_sdp_payload *ast_sdp_payload_alloc(const char *fmt);
+
+/*!
+ * \brief Allocate an SDP Media Description
+ *
+ * \param type ("audio", "video", etc)
+ * \param port Starting port
+ * \param port_count Port pairs to allocate
+ * \param proto ("RTP/AVP", "RTP/SAVP", "udp")
+ * \param c_line Connection to add. May be NULL
+ *
+ * \retval non-NULL Success
+ * \retval NULL Failure
+ *
+ * \since 15
+ */
+struct ast_sdp_m_line *ast_sdp_m_alloc(const char *type, uint16_t port,
+ uint16_t port_count, const char *proto, struct ast_sdp_c_line *c_line);
+
+/*!
+ * \brief Allocate an SDP Session
+ *
+ * \param session_name The session name
+ *
+ * \retval non-NULL Success
+ * \retval NULL Failure
+ *
+ * \since 15
+ */
+struct ast_sdp_s_line *ast_sdp_s_alloc(const char *session_name);
+
+/*!
+ * \brief Allocate SDP Timing
+ *
+ * \param start_time (Seconds since 1900)
+ * \param end_time (Seconds since 1900)
+ *
+ * \retval non-NULL Success
+ * \retval NULL Failure
+ *
+ * \since 15
+ */
+struct ast_sdp_t_line *ast_sdp_t_alloc(uint64_t start_time, uint64_t stop_time);
+
+/*!
+ * \brief Allocate an SDP Origin
+ *
+ * \param username User name
+ * \param sesison_id Session ID
+ * \param sesison_version Session Version
+ * \param address_type Address type ("IN4", "IN6", etc)
+ * \param address Unicast address
+ *
+ * \retval non-NULL Success
+ * \retval NULL Failure
+ *
+ * \since 15
+ */
+struct ast_sdp_o_line *ast_sdp_o_alloc(const char *username, uint64_t session_id,
+ uint64_t session_version, const char *address_type, const char *address);
+
+/*!
+ * \brief Add an SDP Attribute to an SDP
+ *
+ * \param sdp SDP
+ * \param a_line Attribute
+ *
+ * \retval 0 Success
+ * \retval non-0 Failure
+ *
+ * \since 15
+ */
+int ast_sdp_add_a(struct ast_sdp *sdp, struct ast_sdp_a_line *a_line);
+
+/*!
+ * \brief Get the count of Attributes on an SDP
+ *
+ * \param sdp SDP
+ *
+ * \returns Number of Attributes
+ *
+ * \since 15
+ */
+int ast_sdp_get_a_count(const struct ast_sdp *sdp);
+
+/*!
+ * \brief Get an Attribute from an SDP
+ *
+ * \param sdp SDP
+ * \param index Attribute index
+ *
+ * \retval non-NULL Success
+ * \retval NULL Failure
+ *
+ * \since 15
+ */
+struct ast_sdp_a_line *ast_sdp_get_a(const struct ast_sdp *sdp, int index);
+
+/*!
+ * \brief Add a Media Description to an SDP
+ *
+ * \param sdp SDP
+ * \param m_line Media Description
+ *
+ * \retval 0 Success
+ * \retval non-0 Failure
+ *
+ * \since 15
+ */
+int ast_sdp_add_m(struct ast_sdp *sdp, struct ast_sdp_m_line *m_line);
+
+/*!
+ * \brief Add an RTP Media Description to an SDP
+ *
+ * \param sdp SDP
+ * \param sdp_state SDP state information
+ * \param options SDP Options
+ * \param stream_index stream
+ *
+ * \retval 0 Success
+ * \retval non-0 Failure
+ *
+ * \since 15
+ */
+int ast_sdp_add_m_from_rtp_stream(struct ast_sdp *sdp, const struct ast_sdp_state *sdp_state,
+ const struct ast_sdp_options *options, int stream_index);
+
+/*!
+ * \brief Get the count of Media Descriptions on an SDP
+ *
+ * \param sdp SDP
+ *
+ * \returns The number of Media Descriptions
+ *
+ * \since 15
+ */
+int ast_sdp_get_m_count(const struct ast_sdp *sdp);
+
+/*!
+ * \brief Get a Media Descriptions from an SDP
+ *
+ * \param sdp SDP
+ * \param index Media Description index
+ *
+ * \retval non-NULL Success
+ * \retval NULL Failure
+ *
+ * \since 15
+ */
+struct ast_sdp_m_line *ast_sdp_get_m(const struct ast_sdp *sdp, int index);
+
+/*!
+ * \brief Add an SDP Attribute to a Media Description
+ *
+ * \param m_line Media Description
+ * \param a_line Attribute
+ *
+ * \retval 0 Success
+ * \retval non-0 Failure
+ *
+ * \since 15
+ */
+int ast_sdp_m_add_a(struct ast_sdp_m_line *m_line, struct ast_sdp_a_line *a_line);
+
+/*!
+ * \brief Get the count of Attributes on a Media Description
+ *
+ * \param m_line Media Description
+ *
+ * \returns Number of Attributes
+ *
+ * \since 15
+ */
+int ast_sdp_m_get_a_count(const struct ast_sdp_m_line *m_line);
+
+/*!
+ * \brief Get an Attribute from a Media Description
+ *
+ * \param m_line Media Description
+ * \param index Attribute index
+ *
+ * \retval non-NULL Success
+ * \retval NULL Failure
+ *
+ * \since 15
+ */
+struct ast_sdp_a_line *ast_sdp_m_get_a(const struct ast_sdp_m_line *m_line, int index);
+
+/*!
+ * \brief Add a Payload to a Media Description
+ *
+ * \param m_line Media Description
+ * \param payload Payload
+ *
+ * \retval 0 Success
+ * \retval non-0 Failure
+ *
+ * \since 15
+ */
+int ast_sdp_m_add_payload(struct ast_sdp_m_line *m_line,
+ struct ast_sdp_payload *payload);
+
+/*!
+ * \brief Get the count of Payloads on a Media Description
+ *
+ * \param m_line Media Description
+ *
+ * \returns Number of Attributes
+ *
+ * \since 15
+ */
+int ast_sdp_m_get_payload_count(const struct ast_sdp_m_line *m_line);
+
+/*!
+ * \brief Get a Payload from a Media Description
+ *
+ * \param m_line Media Description
+ * \param index Payload index
+ *
+ * \retval non-NULL Success
+ * \retval NULL Failure
+ *
+ * \since 15
+ */
+struct ast_sdp_payload *ast_sdp_m_get_payload(const struct ast_sdp_m_line *m_line, int index);
+
+/*!
+ * \brief Add a Format to a Media Description
+ *
+ * \param m_line Media Description
+ * \param options SDP Options
+ * \param rtp_code rtp_code from ast_rtp_codecs_payload_code
+ * \param asterisk_format True if the value in format is to be used.
+ * \param format Format
+ * \param code from AST_RTP list
+ *
+ * \retval 0 Success
+ * \retval non-0 Failure
+ *
+ * \since 15
+ */
+int ast_sdp_m_add_format(struct ast_sdp_m_line *m_line, const struct ast_sdp_options *options,
+ int rtp_code, int asterisk_format, const struct ast_format *format, int code);
+
+/*!
+ * \brief Create an SDP ao2 object
+ *
+ * \param o_line Origin
+ * \param c_line Connection
+ * \param s_line Session
+ * \param t_line Timing
+ *
+ * \retval non-NULL Success
+ * \retval NULL Failure
+ *
+ * \since 15
+ */
+struct ast_sdp *ast_sdp_alloc(struct ast_sdp_o_line *o_line,
+ struct ast_sdp_c_line *c_line, struct ast_sdp_s_line *s_line,
+ struct ast_sdp_t_line *t_line);
+
+/*!
+ * \brief Find the first attribute match index in the top-level SDP
+ *
+ * \note This will not search within streams for the given attribute.
+ *
+ * \param sdp The SDP in which to search
+ * \param attr_name The name of the attribute to search for
+ * \param payload Optional payload number to search for. If irrelevant, set to -1
+ *
+ * \retval index of attribute line on success.
+ * \retval -1 on failure or not found.
+ *
+ * \since 15.0.0
+ */
+int ast_sdp_find_a_first(const struct ast_sdp *sdp, const char *attr_name, int payload);
+
+/*!
+ * \brief Find the next attribute match index in the top-level SDP
+ *
+ * \note This will not search within streams for the given attribute.
+ *
+ * \param sdp The SDP in which to search
+ * \param last The last matching index found
+ * \param attr_name The name of the attribute to search for
+ * \param payload Optional payload number to search for. If irrelevant, set to -1
+ *
+ * \retval index of attribute line on success.
+ * \retval -1 on failure or not found.
+ *
+ * \since 15.0.0
+ */
+int ast_sdp_find_a_next(const struct ast_sdp *sdp, int last, const char *attr_name, int payload);
+
+/*!
+ * \brief Find an attribute in the top-level SDP
+ *
+ * \note This will not search within streams for the given attribute.
+ *
+ * \param sdp The SDP in which to search
+ * \param attr_name The name of the attribute to search for
+ * \param payload Optional payload number to search for. If irrelevant, set to -1
+ *
+ * \retval NULL Could not find the given attribute
+ * \retval Non-NULL The attribute to find
+ *
+ * \since 15.0.0
+ */
+struct ast_sdp_a_line *ast_sdp_find_attribute(const struct ast_sdp *sdp,
+ const char *attr_name, int payload);
+
+/*!
+ * \brief Find the first attribute match index in an SDP stream (m-line)
+ *
+ * \param m_line The SDP m-line in which to search
+ * \param attr_name The name of the attribute to search for
+ * \param payload Optional payload number to search for. If irrelevant, set to -1
+ *
+ * \retval index of attribute line on success.
+ * \retval -1 on failure or not found.
+ *
+ * \since 15.0.0
+ */
+int ast_sdp_m_find_a_first(const struct ast_sdp_m_line *m_line, const char *attr_name,
+ int payload);
+
+/*!
+ * \brief Find the next attribute match index in an SDP stream (m-line)
+ *
+ * \param m_line The SDP m-line in which to search
+ * \param last The last matching index found
+ * \param attr_name The name of the attribute to search for
+ * \param payload Optional payload number to search for. If irrelevant, set to -1
+ *
+ * \retval index of attribute line on success.
+ * \retval -1 on failure or not found.
+ *
+ * \since 15.0.0
+ */
+int ast_sdp_m_find_a_next(const struct ast_sdp_m_line *m_line, int last,
+ const char *attr_name, int payload);
+
+/*!
+ * \brief Find an attribute in an SDP stream (m-line)
+ *
+ * \param m_line The SDP m-line in which to search
+ * \param attr_name The name of the attribute to search for
+ * \param payload Optional payload number to search for. If irrelevant, set to -1
+ *
+ * \retval NULL Could not find the given attribute
+ * \retval Non-NULL The attribute to find
+ *
+ * \since 15.0.0
+ */
+struct ast_sdp_a_line *ast_sdp_m_find_attribute(const struct ast_sdp_m_line *m_line,
+ const char *attr_name, int payload);
+
+/*!
+ * \brief Convert an SDP a_line into an rtpmap
+ *
+ * The returned value is heap-allocated and must be freed with
+ * ast_sdp_rtpmap_free()
+ *
+ * \param a_line The SDP a_line to convert
+ *
+ * \retval NULL Fail
+ * \retval non-NULL Success
+ *
+ * \since 15.0.0
+ */
+struct ast_sdp_rtpmap *ast_sdp_a_get_rtpmap(const struct ast_sdp_a_line *a_line);
+
+
+/*!
+ * \brief Allocate a new SDP rtpmap
+ *
+ * \param payload The RTP payload number
+ * \param encoding_name The human-readable name for the codec
+ * \param clock_rate The rate of the codec, in cycles per second
+ * \param encoding_parameters Optional codec-specific parameters (such as number of channels)
+ *
+ * \retval NULL Fail
+ * \retval non-NULL Success
+ *
+ * \since 15.0.0
+ */
+struct ast_sdp_rtpmap *ast_sdp_rtpmap_alloc(int payload, const char *encoding_name,
+ int clock_rate, const char *encoding_parameters);
+
+/*!
+ * \brief Free an SDP rtpmap
+ *
+ * \since 15.0.0
+ */
+void ast_sdp_rtpmap_free(struct ast_sdp_rtpmap *rtpmap);
+
+/*!
+ * \brief Turn an SDP into a stream topology
+ *
+ * This traverses the m-lines of the SDP and creates a stream topology, with
+ * each m-line corresponding to a stream in the created topology.
+ *
+ * \param sdp The SDP to convert
+ * \param g726_non_standard Non-zero if G.726 is non-standard
+ *
+ * \retval NULL An error occurred when converting
+ * \retval non-NULL The generated stream topology
+ *
+ * \since 15.0.0
+ */
+struct ast_stream_topology *ast_get_topology_from_sdp(const struct ast_sdp *sdp, int g726_non_standard);
+#endif /* _SDP_PRIV_H */
diff --git a/include/asterisk/sdp_options.h b/include/asterisk/sdp_options.h
index a5c2d084e..e45ae8cb1 100644
--- a/include/asterisk/sdp_options.h
+++ b/include/asterisk/sdp_options.h
@@ -19,9 +19,211 @@
#ifndef _ASTERISK_SDP_OPTIONS_H
#define _ASTERISK_SDP_OPTIONS_H
+#include "asterisk/udptl.h"
+#include "asterisk/format_cap.h"
+
struct ast_sdp_options;
/*!
+ * \brief SDP DTMF mode options
+ */
+enum ast_sdp_options_dtmf {
+ /*! No DTMF to be used */
+ AST_SDP_DTMF_NONE,
+ /*! Use RFC 4733 events for DTMF */
+ AST_SDP_DTMF_RFC_4733,
+ /*! Use DTMF in the audio stream */
+ AST_SDP_DTMF_INBAND,
+ /*! Use SIP 4733 if supported by the other side or INBAND if not */
+ AST_SDP_DTMF_AUTO,
+};
+
+/*!
+ * \brief ICE options
+ *
+ * This is an enum because it will support a TRICKLE-ICE option
+ * in the future.
+ */
+enum ast_sdp_options_ice {
+ /*! ICE is not enabled on this session */
+ AST_SDP_ICE_DISABLED,
+ /*! Standard ICE is enabled on this session */
+ AST_SDP_ICE_ENABLED_STANDARD,
+};
+
+/*!
+ * \brief Implementation of the SDP
+ *
+ * Users of the SDP API set the implementation based on what they
+ * natively handle. This indicates the type of SDP that the API expects
+ * when being given an SDP, and it indicates the type of SDP that the API
+ * returns when asked for one.
+ */
+enum ast_sdp_options_impl {
+ /*! SDP is represented as a string */
+ AST_SDP_IMPL_STRING,
+ /*! SDP is represented as a pjmedia_sdp_session */
+ AST_SDP_IMPL_PJMEDIA,
+ /*! End of the list */
+ AST_SDP_IMPL_END,
+};
+
+/*!
+ * \brief SDP encryption options
+ */
+enum ast_sdp_options_encryption {
+ /*! No encryption */
+ AST_SDP_ENCRYPTION_DISABLED,
+ /*! SRTP SDES encryption */
+ AST_SDP_ENCRYPTION_SRTP_SDES,
+ /*! DTLS encryption */
+ AST_SDP_ENCRYPTION_DTLS,
+};
+
+/*!
+ * \brief Callback when processing an offer SDP for our answer SDP.
+ * \since 15.0.0
+ *
+ * \details
+ * This callback is called after merging our last negotiated topology
+ * with the remote's offer topology and before we have sent our answer
+ * SDP. At this point you can alter new_topology streams. You can
+ * decline, remove formats, or rename streams. Changing anything else
+ * on the streams is likely to not end well.
+ *
+ * * To decline a stream simply set the stream state to
+ * AST_STREAM_STATE_REMOVED. You could implement a maximum number
+ * of active streams of a given type policy.
+ *
+ * * To remove formats use the format API to remove any formats from a
+ * stream. The streams have the current joint negotiated formats.
+ * Most likely you would want to remove all but the first format.
+ *
+ * * To rename a stream you need to clone the stream and give it a
+ * new name and then set it in new_topology using
+ * ast_stream_topology_set_stream().
+ *
+ * \note Removing all formats is an error. You should decline the
+ * stream instead.
+ *
+ * \param context User supplied context data pointer for the SDP
+ * state.
+ * \param old_topology Active negotiated topology. NULL if this is
+ * the first SDP negotiation. The old topology is available so you
+ * can tell if any streams are new or changing type.
+ * \param new_topology New negotiated topology that we intend to
+ * generate the answer SDP.
+ *
+ * \return Nothing
+ */
+typedef void (*ast_sdp_answerer_modify_cb)(void *context,
+ const struct ast_stream_topology *old_topology,
+ struct ast_stream_topology *new_topology);
+
+/*!
+ * \internal
+ * \brief Callback when generating a topology for our SDP offer.
+ * \since 15.0.0
+ *
+ * \details
+ * This callback is called after merging any topology updates from the
+ * system by ast_sdp_state_update_local_topology() and before we have
+ * sent our offer SDP. At this point you can alter new_topology
+ * streams. You can decline, add/remove/update formats, or rename
+ * streams. Changing anything else on the streams is likely to not
+ * end well.
+ *
+ * * To decline a stream simply set the stream state to
+ * AST_STREAM_STATE_REMOVED. You could implement a maximum number
+ * of active streams of a given type policy.
+ *
+ * * To update formats use the format API to change formats of the
+ * streams. The streams have the current proposed formats. You
+ * could do whatever you want for formats but you should stay within
+ * the configured formats for the stream type's endpoint. However,
+ * you should use ast_sdp_state_update_local_topology() instead of
+ * this backdoor method.
+ *
+ * * To rename a stream you need to clone the stream and give it a
+ * new name and then set it in new_topology using
+ * ast_stream_topology_set_stream().
+ *
+ * \note Removing all formats is an error. You should decline the
+ * stream instead.
+ *
+ * \note Declined new streams that are in slots higher than present in
+ * old_topology are removed so the SDP can be smaller. The remote has
+ * never seen those slots so we shouldn't bother keeping them.
+ *
+ * \param context User supplied context data pointer for the SDP
+ * state.
+ * \param old_topology Active negotiated topology. NULL if this is
+ * the first SDP negotiation. The old topology is available so you
+ * can tell if any streams are new or changing type.
+ * \param new_topology Merged topology that we intend to generate the
+ * offer SDP.
+ *
+ * \return Nothing
+ */
+typedef void (*ast_sdp_offerer_modify_cb)(void *context,
+ const struct ast_stream_topology *old_topology,
+ struct ast_stream_topology *new_topology);
+
+/*!
+ * \brief Callback when generating an offer SDP to configure extra stream data.
+ * \since 15.0.0
+ *
+ * \details
+ * This callback is called after any ast_sdp_offerer_modify_cb
+ * callback and before we have sent our offer SDP. The callback can
+ * call several SDP API calls to configure the proposed capabilities
+ * of streams before we create the SDP offer. For example, the
+ * callback could configure a stream specific connection address, T.38
+ * parameters, RTP instance, or UDPTL instance parameters.
+ *
+ * \param context User supplied context data pointer for the SDP
+ * state.
+ * \param topology Topology ready to configure extra stream options.
+ *
+ * \return Nothing
+ */
+typedef void (*ast_sdp_offerer_config_cb)(void *context, const struct ast_stream_topology *topology);
+
+/*!
+ * \brief Callback before applying a topology.
+ * \since 15.0.0
+ *
+ * \details
+ * This callback is called before the topology is applied so the
+ * using module can do what is necessary before the topology becomes
+ * active.
+ *
+ * \param context User supplied context data pointer for the SDP
+ * state.
+ * \param topology Topology ready to be applied.
+ *
+ * \return Nothing
+ */
+typedef void (*ast_sdp_preapply_cb)(void *context, const struct ast_stream_topology *topology);
+
+/*!
+ * \brief Callback after applying a topology.
+ * \since 15.0.0
+ *
+ * \details
+ * This callback is called after the topology is applied so the
+ * using module can do what is necessary after the topology becomes
+ * active.
+ *
+ * \param context User supplied context data pointer for the SDP
+ * state.
+ * \param topology Topology already applied.
+ *
+ * \return Nothing
+ */
+typedef void (*ast_sdp_postapply_cb)(void *context, const struct ast_stream_topology *topology);
+
+/*!
* \since 15.0.0
* \brief Allocate a new SDP options structure.
*
@@ -47,111 +249,526 @@ struct ast_sdp_options *ast_sdp_options_alloc(void);
void ast_sdp_options_free(struct ast_sdp_options *options);
/*!
- * \brief ICE options
+ * \since 15.0.0
+ * \brief Set SDP Options media_address
*
- * This is an enum because it is predicted that this eventually
- * support a TRICKLE-ICE option.
+ * \param options SDP Options
+ * \param media_address
*/
-enum ast_sdp_options_ice {
- /*! ICE is not enabled on this session */
- AST_SDP_ICE_DISABLED,
- /*! Standard ICE is enabled on this session */
- AST_SDP_ICE_ENABLED_STANDARD,
-};
+void ast_sdp_options_set_media_address(struct ast_sdp_options *options,
+ const char *media_address);
/*!
* \since 15.0.0
- * \brief Set ICE options
+ * \brief Get SDP Options media_address
*
- * The default is AST_SDP_ICE_DISABLED
+ * \param options SDP Options
+ *
+ * \returns media_address
*/
-int ast_sdp_options_set_ice(struct ast_sdp_options *options,
- enum ast_sdp_options_ice ice_setting);
+const char *ast_sdp_options_get_media_address(const struct ast_sdp_options *options);
/*!
* \since 15.0.0
- * \brief Retrieve ICE options
+ * \brief Set SDP Options interface_address
+ *
+ * \param options SDP Options
+ * \param interface_address
*/
-enum ast_sdp_options_ice ast_sdp_options_get_ice(const struct ast_sdp_options *options);
+void ast_sdp_options_set_interface_address(struct ast_sdp_options *options,
+ const char *interface_address);
/*!
* \since 15.0.0
- * \brief Enable or disable telephone events.
+ * \brief Get SDP Options interface_address
*
- * A non-zero value indicates telephone events are enabled.
- * A zero value indicates telephone events are disabled.
+ * \param options SDP Options
*
- * The default is 0
+ * \returns interface_address
*/
-int ast_sdp_options_set_telephone_event(struct ast_sdp_options *options,
- int telephone_event_enabled);
+const char *ast_sdp_options_get_interface_address(const struct ast_sdp_options *options);
/*!
* \since 15.0.0
- * \brief Retrieve telephone event setting.
+ * \brief Set SDP Options sdpowner
*
- * \retval 0 Telephone events are currently disabled.
- * \retval non-zero Telephone events are currently enabled.
+ * \param options SDP Options
+ * \param sdpowner
*/
-int ast_sdp_options_get_telephone_event(const struct ast_sdp_options *options);
+void ast_sdp_options_set_sdpowner(struct ast_sdp_options *options,
+ const char *sdpowner);
/*!
- * \brief Representation of the SDP
+ * \since 15.0.0
+ * \brief Get SDP Options sdpowner
*
- * Users of the SDP API set the representation based on what they
- * natively handle. This indicates the type of SDP that the API expects
- * when being given an SDP, and it indicates the type of SDP that the API
- * returns when asked for one.
+ * \param options SDP Options
+ *
+ * \returns sdpowner
*/
-enum ast_sdp_options_repr {
- /*! SDP is represented as a string */
- AST_SDP_REPR_STRING,
- /*! SDP is represented as a pjmedia_sdp_session */
- AST_SDP_REPR_PJMEDIA,
- /*! End of the list */
- AST_SDP_REPR_END,
-};
+const char *ast_sdp_options_get_sdpowner(const struct ast_sdp_options *options);
/*!
* \since 15.0.0
- * \brief Set the SDP representation
+ * \brief Set SDP Options sdpsession
*
- * The default is AST_SDP_REPR_STRING
+ * \param options SDP Options
+ * \param sdpsession
*/
-int ast_sdp_options_set_repr(struct ast_sdp_options *options,
- enum ast_sdp_options_repr repr);
+void ast_sdp_options_set_sdpsession(struct ast_sdp_options *options,
+ const char *sdpsession);
/*!
* \since 15.0.0
- * \brief Get the SDP representation
+ * \brief Get SDP Options sdpsession
+ *
+ * \param options SDP Options
+ *
+ * \returns sdpsession
*/
-enum ast_sdp_options_repr ast_sdp_options_get_repr(const struct ast_sdp_options *options);
+const char *ast_sdp_options_get_sdpsession(const struct ast_sdp_options *options);
/*!
- * \brief SDP encryption options
+ * \since 15.0.0
+ * \brief Set SDP Options rtp_engine
+ *
+ * \param options SDP Options
+ * \param rtp_engine
*/
-enum ast_sdp_options_encryption {
- /*! No encryption */
- AST_SDP_ENCRYPTION_DISABLED,
- /*! SRTP SDES encryption */
- AST_SDP_ENCRYPTION_SRTP_SDES,
- /*! DTLS encryption */
- AST_SDP_ENCRYPTION_DTLS,
-};
+void ast_sdp_options_set_rtp_engine(struct ast_sdp_options *options,
+ const char *rtp_engine);
+
+/*!
+ * \since 15.0.0
+ * \brief Get SDP Options rtp_engine
+ *
+ * \param options SDP Options
+ *
+ * \returns rtp_engine
+ */
+const char *ast_sdp_options_get_rtp_engine(const struct ast_sdp_options *options);
+
+void ast_sdp_options_set_state_context(struct ast_sdp_options *options, void *state_context);
+void *ast_sdp_options_get_state_context(const struct ast_sdp_options *options);
+
+void ast_sdp_options_set_answerer_modify_cb(struct ast_sdp_options *options, ast_sdp_answerer_modify_cb answerer_modify_cb);
+ast_sdp_answerer_modify_cb ast_sdp_options_get_answerer_modify_cb(const struct ast_sdp_options *options);
+
+void ast_sdp_options_set_offerer_modify_cb(struct ast_sdp_options *options, ast_sdp_offerer_modify_cb offerer_modify_cb);
+ast_sdp_offerer_modify_cb ast_sdp_options_get_offerer_modify_cb(const struct ast_sdp_options *options);
+
+void ast_sdp_options_set_offerer_config_cb(struct ast_sdp_options *options, ast_sdp_offerer_config_cb offerer_config_cb);
+ast_sdp_offerer_config_cb ast_sdp_options_get_offerer_config_cb(const struct ast_sdp_options *options);
+
+void ast_sdp_options_set_preapply_cb(struct ast_sdp_options *options, ast_sdp_preapply_cb preapply_cb);
+ast_sdp_preapply_cb ast_sdp_options_get_preapply_cb(const struct ast_sdp_options *options);
+
+void ast_sdp_options_set_postapply_cb(struct ast_sdp_options *options, ast_sdp_postapply_cb postapply_cb);
+ast_sdp_postapply_cb ast_sdp_options_get_postapply_cb(const struct ast_sdp_options *options);
+
+/*!
+ * \since 15.0.0
+ * \brief Set SDP Options rtp_symmetric
+ *
+ * \param options SDP Options
+ * \param rtp_symmetric
+ */
+void ast_sdp_options_set_rtp_symmetric(struct ast_sdp_options *options,
+ unsigned int rtp_symmetric);
+
+/*!
+ * \since 15.0.0
+ * \brief Get SDP Options rtp_symmetric
+ *
+ * \param options SDP Options
+ *
+ * \returns rtp_symmetric
+ */
+unsigned int ast_sdp_options_get_rtp_symmetric(const struct ast_sdp_options *options);
+
+/*!
+ * \since 15.0.0
+ * \brief Set SDP Options rtp_ipv6
+ *
+ * \param options SDP Options
+ * \param rtp_ipv6
+ */
+void ast_sdp_options_set_rtp_ipv6(struct ast_sdp_options *options,
+ unsigned int rtp_ipv6);
+
+/*!
+ * \since 15.0.0
+ * \brief Get SDP Options rtp_ipv6
+ *
+ * \param options SDP Options
+ *
+ * \returns rtp_ipv6
+ */
+unsigned int ast_sdp_options_get_rtp_ipv6(const struct ast_sdp_options *options);
+
+/*!
+ * \since 15.0.0
+ * \brief Set SDP Options g726_non_standard
+ *
+ * \param options SDP Options
+ * \param g726_non_standard
+ */
+void ast_sdp_options_set_g726_non_standard(struct ast_sdp_options *options,
+ unsigned int g726_non_standard);
+
+/*!
+ * \since 15.0.0
+ * \brief Get SDP Options g726_non_standard
+ *
+ * \param options SDP Options
+ *
+ * \returns g726_non_standard
+ */
+unsigned int ast_sdp_options_get_g726_non_standard(const struct ast_sdp_options *options);
+
+/*!
+ * \since 15.0.0
+ * \brief Set SDP Options tos_audio
+ *
+ * \param options SDP Options
+ * \param tos_audio
+ */
+void ast_sdp_options_set_tos_audio(struct ast_sdp_options *options,
+ unsigned int tos_audio);
+
+/*!
+ * \since 15.0.0
+ * \brief Get SDP Options tos_audio
+ *
+ * \param options SDP Options
+ *
+ * \returns tos_audio
+ */
+unsigned int ast_sdp_options_get_tos_audio(const struct ast_sdp_options *options);
+
+/*!
+ * \since 15.0.0
+ * \brief Set SDP Options cos_audio
+ *
+ * \param options SDP Options
+ * \param cos_audio
+ */
+void ast_sdp_options_set_cos_audio(struct ast_sdp_options *options,
+ unsigned int cos_audio);
+
+/*!
+ * \since 15.0.0
+ * \brief Get SDP Options cos_audio
+ *
+ * \param options SDP Options
+ *
+ * \returns cos_audio
+ */
+unsigned int ast_sdp_options_get_cos_audio(const struct ast_sdp_options *options);
/*!
* \since 15.0.0
- * \brief Set the SDP encryption
+ * \brief Set SDP Options tos_video
*
- * The default is AST_SDP_ENCRYPTION_DISABLED
+ * \param options SDP Options
+ * \param tos_video
*/
-int ast_sdp_options_set_encryption(struct ast_sdp_options *options,
+void ast_sdp_options_set_tos_video(struct ast_sdp_options *options,
+ unsigned int tos_video);
+
+/*!
+ * \since 15.0.0
+ * \brief Get SDP Options tos_video
+ *
+ * \param options SDP Options
+ *
+ * \returns tos_video
+ */
+unsigned int ast_sdp_options_get_tos_video(const struct ast_sdp_options *options);
+
+/*!
+ * \since 15.0.0
+ * \brief Set SDP Options cos_video
+ *
+ * \param options SDP Options
+ * \param cos_video
+ */
+void ast_sdp_options_set_cos_video(struct ast_sdp_options *options,
+ unsigned int cos_video);
+
+/*!
+ * \since 15.0.0
+ * \brief Get SDP Options cos_video
+ *
+ * \param options SDP Options
+ *
+ * \returns cos_video
+ */
+unsigned int ast_sdp_options_get_cos_video(const struct ast_sdp_options *options);
+
+/*!
+ * \since 15.0.0
+ * \brief Set SDP Options dtmf
+ *
+ * \param options SDP Options
+ * \param dtmf
+ */
+void ast_sdp_options_set_dtmf(struct ast_sdp_options *options,
+ enum ast_sdp_options_dtmf dtmf);
+
+/*!
+ * \since 15.0.0
+ * \brief Get SDP Options dtmf
+ *
+ * \param options SDP Options
+ *
+ * \returns dtmf
+ */
+enum ast_sdp_options_dtmf ast_sdp_options_get_dtmf(const struct ast_sdp_options *options);
+
+/*!
+ * \since 15.0.0
+ * \brief Set SDP Options ice
+ *
+ * \param options SDP Options
+ * \param ice
+ */
+void ast_sdp_options_set_ice(struct ast_sdp_options *options,
+ enum ast_sdp_options_ice ice);
+
+/*!
+ * \since 15.0.0
+ * \brief Get SDP Options ice
+ *
+ * \param options SDP Options
+ *
+ * \returns ice
+ */
+enum ast_sdp_options_ice ast_sdp_options_get_ice(const struct ast_sdp_options *options);
+
+/*!
+ * \since 15.0.0
+ * \brief Set SDP Options impl
+ *
+ * \param options SDP Options
+ * \param impl
+ */
+void ast_sdp_options_set_impl(struct ast_sdp_options *options,
+ enum ast_sdp_options_impl impl);
+
+/*!
+ * \since 15.0.0
+ * \brief Get SDP Options impl
+ *
+ * \param options SDP Options
+ *
+ * \returns impl
+ */
+enum ast_sdp_options_impl ast_sdp_options_get_impl(const struct ast_sdp_options *options);
+
+/*!
+ * \since 15.0.0
+ * \brief Set SDP Options encryption
+ *
+ * \param options SDP Options
+ * \param encryption
+ */
+void ast_sdp_options_set_encryption(struct ast_sdp_options *options,
enum ast_sdp_options_encryption encryption);
/*!
* \since 15.0.0
- * \brief Get the SDP encryption
+ * \brief Get SDP Options encryption
+ *
+ * \param options SDP Options
+ *
+ * \returns encryption
*/
enum ast_sdp_options_encryption ast_sdp_options_get_encryption(const struct ast_sdp_options *options);
+/*!
+ * \since 15.0.0
+ * \brief Get SDP Options RTCP MUX
+ *
+ * \param options SDP Options
+ *
+ * \returns Boolean indicating if RTCP MUX is enabled.
+ */
+unsigned int ast_sdp_options_get_rtcp_mux(const struct ast_sdp_options *options);
+
+/*!
+ * \since 15.0.0
+ * \brief Set SDP Options RTCP MUX
+ *
+ * \param options SDP Options
+ * \param value Boolean that indicates if RTCP MUX should be enabled.
+ */
+void ast_sdp_options_set_rtcp_mux(struct ast_sdp_options *options, unsigned int value);
+
+/*!
+ * \since 15.0.0
+ * \brief Set SDP Options udptl_symmetric
+ *
+ * \param options SDP Options
+ * \param udptl_symmetric
+ */
+void ast_sdp_options_set_udptl_symmetric(struct ast_sdp_options *options,
+ unsigned int udptl_symmetric);
+
+/*!
+ * \since 15.0.0
+ * \brief Get SDP Options udptl_symmetric
+ *
+ * \param options SDP Options
+ *
+ * \returns udptl_symmetric
+ */
+unsigned int ast_sdp_options_get_udptl_symmetric(const struct ast_sdp_options *options);
+
+/*!
+ * \since 15.0.0
+ * \brief Set SDP Options udptl_error_correction
+ *
+ * \param options SDP Options
+ * \param error_correction
+ */
+void ast_sdp_options_set_udptl_error_correction(struct ast_sdp_options *options,
+ enum ast_t38_ec_modes error_correction);
+
+/*!
+ * \since 15.0.0
+ * \brief Get SDP Options udptl_error_correction
+ *
+ * \param options SDP Options
+ *
+ * \returns udptl_error_correction
+ */
+enum ast_t38_ec_modes ast_sdp_options_get_udptl_error_correction(const struct ast_sdp_options *options);
+
+/*!
+ * \since 15.0.0
+ * \brief Set SDP Options udptl_far_max_datagram
+ *
+ * \param options SDP Options
+ * \param far_max_datagram
+ */
+void ast_sdp_options_set_udptl_far_max_datagram(struct ast_sdp_options *options,
+ unsigned int far_max_datagram);
+
+/*!
+ * \since 15.0.0
+ * \brief Get SDP Options udptl_far_max_datagram
+ *
+ * \param options SDP Options
+ *
+ * \returns udptl_far_max_datagram
+ */
+unsigned int ast_sdp_options_get_udptl_far_max_datagram(const struct ast_sdp_options *options);
+
+/*!
+ * \since 15.0.0
+ * \brief Set SDP Options max_streams
+ *
+ * \param options SDP Options
+ * \param max_streams
+ */
+void ast_sdp_options_set_max_streams(struct ast_sdp_options *options,
+ unsigned int max_streams);
+
+/*!
+ * \since 15.0.0
+ * \brief Get SDP Options max_streams
+ *
+ * \param options SDP Options
+ *
+ * \returns max_streams
+ */
+unsigned int ast_sdp_options_get_max_streams(const struct ast_sdp_options *options);
+
+/*!
+ * \since 15.0.0
+ * \brief Enable setting SSRC level attributes on SDPs
+ *
+ * \param options SDP Options
+ * \param ssrc Boolean indicating if SSRC attributes should be included in generated SDPs
+ */
+void ast_sdp_options_set_ssrc(struct ast_sdp_options *options, unsigned int ssrc);
+
+/*!
+ * \since 15.0.0
+ * \brief Get SDP Options ssrc
+ *
+ * \param options SDP Options
+ *
+ * \returns Whether SSRC-level attributes will be added to our SDP.
+ */
+unsigned int ast_sdp_options_get_ssrc(const struct ast_sdp_options *options);
+
+/*!
+ * \brief Set the SDP options scheduler context used to create new streams of the type.
+ * \since 15.0.0
+ *
+ * \param options SDP Options
+ * \param type Media type the scheduler context is for.
+ * \param sched Scheduler context to use for the specified media type.
+ *
+ * \return Nothing
+ */
+void ast_sdp_options_set_sched_type(struct ast_sdp_options *options,
+ enum ast_media_type type, struct ast_sched_context *sched);
+
+/*!
+ * \brief Get the SDP options scheduler context used to create new streams of the type.
+ * \since 15.0.0
+ *
+ * \param options SDP Options
+ * \param type Media type the format cap represents.
+ *
+ * \return The stored scheduler context to create new streams of the type.
+ */
+struct ast_sched_context *ast_sdp_options_get_sched_type(const struct ast_sdp_options *options,
+ enum ast_media_type type);
+
+/*!
+ * \brief Set all allowed stream types to create new streams.
+ * \since 15.0.0
+ *
+ * \param options SDP Options
+ * \param cap Format capabilities to set all allowed stream types at once.
+ * Could be NULL to disable creating any new streams.
+ *
+ * \return Nothing
+ */
+void ast_sdp_options_set_format_caps(struct ast_sdp_options *options,
+ struct ast_format_cap *cap);
+
+/*!
+ * \brief Set the SDP options format cap used to create new streams of the type.
+ * \since 15.0.0
+ *
+ * \param options SDP Options
+ * \param type Media type the format cap represents.
+ * \param cap Format capabilities to use for the specified media type.
+ * Could be NULL to disable creating new streams of type.
+ *
+ * \return Nothing
+ */
+void ast_sdp_options_set_format_cap_type(struct ast_sdp_options *options,
+ enum ast_media_type type, struct ast_format_cap *cap);
+
+/*!
+ * \brief Get the SDP options format cap used to create new streams of the type.
+ * \since 15.0.0
+ *
+ * \param options SDP Options
+ * \param type Media type the format cap represents.
+ *
+ * \retval NULL if stream not allowed to be created.
+ * \retval cap to use in negotiating the new stream.
+ *
+ * \note The returned cap does not have its own ao2 ref.
+ */
+struct ast_format_cap *ast_sdp_options_get_format_cap_type(const struct ast_sdp_options *options,
+ enum ast_media_type type);
+
#endif /* _ASTERISK_SDP_OPTIONS_H */
diff --git a/include/asterisk/sdp_priv.h b/include/asterisk/sdp_priv.h
deleted file mode 100644
index 000d11143..000000000
--- a/include/asterisk/sdp_priv.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2017, 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.
- */
-
-/* NOTE: It is unlikely that you need to include this file. You probably will only need
- * this if you are an SDP translator, or if you are an inner part of the SDP API
- */
-
-#ifndef _SDP_PRIV_H
-#define _SDP_PRIV_H
-
-#include "asterisk/vector.h"
-
-/*!
- * \brief Structure representing an SDP attribute
- */
-struct ast_sdp_a_line {
- /*! Attribute name */
- char *name;
- /*! Attribute value. For attributes that have no value, this will be an empty string */
- char *value;
-};
-
-/*!
- * \brief Structure representing an SDP connection
- */
-struct ast_sdp_c_line {
- /* IP family string (e.g. IP4 or IP6) */
- char *family;
- /* Connection address. Can be an IP address or FQDN */
- char *addr;
-};
-
-/*!
- * \brief A collection of SDP attributes
- */
-AST_VECTOR(ast_sdp_a_line_vector, struct ast_sdp_a_line);
-
-/*!
- * \brief An SDP media stream
- *
- * This contains both the m line, as well as its
- * constituent a lines.
- */
-struct ast_sdp_m_line {
- /*! Media type (e.g. "audio" or "video") */
- char *type;
- /*! Port number in m line */
- uint16_t port;
- /*! Number of ports specified in m line */
- uint16_t port_count;
- /*! RTP profile string (e.g. "RTP/AVP") */
- char *profile;
- /*! RTP payloads */
- AST_VECTOR(, char *) payloads;
- /*! Connection information for this media stream */
- struct ast_sdp_c_line c_line;
- /*! The attributes for this media stream */
- struct ast_sdp_a_line_vector a_lines;
-};
-
-/*!
- * \brief SDP time information
- */
-struct ast_sdp_t_line {
- /*! Session start time */
- uint32_t start;
- /*! Session end time */
- uint32_t end;
-};
-
-/*!
- * \brief An SDP
- */
-struct ast_sdp {
- /*! SDP Origin line */
- struct {
- /*! Origin user name */
- char *user;
- /*! Origin id */
- uint32_t id;
- /*! Origin version */
- uint32_t version;
- /*! Origin IP address family (e.g. "IP4" or "IP6") */
- char *family;
- /*! Origin address. Can be an IP address or FQDN */
- char *addr;
- } o_line;
- /*! SDP Session name */
- char *s_line;
- /*! SDP top-level connection information */
- struct ast_sdp_c_line c_line;
- /*! SDP timing information */
- struct ast_sdp_t_line t_line;
- /*! SDP top-level attributes */
- struct ast_sdp_a_line_vector a_lines;
- /*! SDP media streams */
- AST_VECTOR(, struct ast_sdp_m_line) m_lines;
-};
-
-/*!
- * \brief Allocate a new SDP.
- *
- * \note This does not perform any initialization.
- *
- * \retval NULL FAIL
- * \retval non-NULL New SDP
- */
-struct ast_sdp *ast_sdp_alloc(void);
-
-/*!
- * \brief Free an SDP and all its constituent parts
- */
-void ast_sdp_free(struct ast_sdp *dead);
-
-#endif /* _SDP_PRIV_H */
diff --git a/include/asterisk/sdp_state.h b/include/asterisk/sdp_state.h
index b5e44179e..ec9d502e2 100644
--- a/include/asterisk/sdp_state.h
+++ b/include/asterisk/sdp_state.h
@@ -19,19 +19,34 @@
#ifndef _ASTERISK_SDP_STATE_H
#define _ASTERISK_SDP_STATE_H
+#include "asterisk/stream.h"
+#include "asterisk/sdp_options.h"
+
struct ast_sdp_state;
-struct ast_sdp_options;
-struct ast_stream_topology;
+struct ast_sockaddr;
+struct ast_udptl;
+struct ast_control_t38_parameters;
/*!
* \brief Allocate a new SDP state
*
+ * \details
* SDP state keeps tabs on everything SDP-related for a media session.
* Most SDP operations will require the state to be provided.
* Ownership of the SDP options is taken on by the SDP state.
* A good strategy is to call this during session creation.
+ *
+ * \param topology Initial stream topology to offer.
+ * NULL if we are going to be the answerer. We can always
+ * update the local topology later if it turns out we need
+ * to be the offerer.
+ * \param options SDP options for the duration of the session.
+ *
+ * \retval SDP state struct
+ * \retval NULL on failure
*/
-struct ast_sdp_state *ast_sdp_state_alloc(struct ast_stream_topology *streams, struct ast_sdp_options *options);
+struct ast_sdp_state *ast_sdp_state_alloc(struct ast_stream_topology *topology,
+ struct ast_sdp_options *options);
/*!
* \brief Free the SDP state.
@@ -45,14 +60,286 @@ void ast_sdp_state_free(struct ast_sdp_state *sdp_state);
*
* Stream numbers correspond to the streams in the topology of the associated channel
*/
-struct ast_rtp_instance *ast_sdp_state_get_rtp_instance(struct ast_sdp_state *sdp_state, int stream_index);
+struct ast_rtp_instance *ast_sdp_state_get_rtp_instance(const struct ast_sdp_state *sdp_state,
+ int stream_index);
+
+/*!
+ * \brief Get the associated UDPTL instance for a particular stream on the SDP state.
+ *
+ * Stream numbers correspond to the streams in the topology of the associated channel
+ */
+struct ast_udptl *ast_sdp_state_get_udptl_instance(const struct ast_sdp_state *sdp_state,
+ int stream_index);
+
+/*!
+ * \brief Get the global connection address on the SDP state.
+ */
+const struct ast_sockaddr *ast_sdp_state_get_connection_address(const struct ast_sdp_state *sdp_state);
+
+/*!
+ * \brief Get the connection address for a particular stream.
+ *
+ * \param sdp_state
+ * \param stream_index The particular stream to get the connection address of
+ * \param address[out] A place to store the address in
+ *
+ * \retval 0 Success
+ *
+ * \note
+ * Stream numbers correspond to the streams in the topology of the associated channel
+ */
+int ast_sdp_state_get_stream_connection_address(const struct ast_sdp_state *sdp_state,
+ int stream_index, struct ast_sockaddr *address);
/*!
* \brief Get the joint negotiated streams based on local and remote capabilities.
*
* If this is called prior to receiving a remote SDP, then this will just mirror
* the local configured endpoint capabilities.
+ *
+ * \note Cannot return NULL. It is a BUG if it does.
+ */
+const struct ast_stream_topology *ast_sdp_state_get_joint_topology(
+ const struct ast_sdp_state *sdp_state);
+
+/*!
+ * \brief Get the local topology
+ *
+ * \note Cannot return NULL. It is a BUG if it does.
+ */
+const struct ast_stream_topology *ast_sdp_state_get_local_topology(
+ const struct ast_sdp_state *sdp_state);
+
+/*!
+ * \brief Get the sdp_state options
+ *
+ */
+const struct ast_sdp_options *ast_sdp_state_get_options(
+ const struct ast_sdp_state *sdp_state);
+
+
+/*!
+ * \brief Get the local SDP.
+ *
+ * \param sdp_state
+ *
+ * \retval non-NULL Success
+ * \retval NULL Failure
+ *
+ * \note
+ * This function will return the last local SDP created if one were
+ * previously requested for the current negotiation. Otherwise it
+ * creates our SDP offer/answer depending on what role we are playing
+ * in the current negotiation.
+ */
+const struct ast_sdp *ast_sdp_state_get_local_sdp(struct ast_sdp_state *sdp_state);
+
+/*!
+ * \brief Get the local SDP Implementation.
+ *
+ * \param sdp_state
+ *
+ * \retval non-NULL Success
+ * \retval NULL Failure
+ *
+ * \note
+ * This function calls ast_sdp_state_get_local_sdp then translates it into
+ * the defined implementation.
+ *
+ * The return here is const. The use case for this is so that a channel can add
+ * the SDP to an outgoing message. The API user should not attempt to modify the SDP.
+ * SDP modification should only be done through the API.
+ *
+ * \since 15
+ */
+const void *ast_sdp_state_get_local_sdp_impl(struct ast_sdp_state *sdp_state);
+
+/*!
+ * \brief Set the remote SDP
+ *
+ * \param sdp_state
+ * \param sdp
+ *
+ * \note It is assumed that the passed in SDP has been checked for sanity
+ * already. e.g., There are no syntax errors, a c= line is reachable for
+ * each m= line, etc...
+ *
+ * \retval 0 Success
+ * \retval non-0 Failure
+ * Use ast_sdp_state_is_offer_rejected() to see if the SDP offer was rejected.
+ *
+ * \since 15
+ */
+int ast_sdp_state_set_remote_sdp(struct ast_sdp_state *sdp_state, const struct ast_sdp *sdp);
+
+/*!
+ * \brief Set the remote SDP from an Implementation
+ *
+ * \param sdp_state
+ * \param remote The implementation's representation of an SDP.
+ *
+ * \retval 0 Success
+ * \retval non-0 Failure
+ * Use ast_sdp_state_is_offer_rejected() to see if the SDP offer was rejected.
+ *
+ * \since 15
+ */
+int ast_sdp_state_set_remote_sdp_from_impl(struct ast_sdp_state *sdp_state, const void *remote);
+
+/*!
+ * \brief Was the set remote offer rejected.
+ * \since 15.0.0
+ *
+ * \param sdp_state
+ *
+ * \retval 0 if not rejected.
+ * \retval non-zero if rejected.
+ */
+int ast_sdp_state_is_offer_rejected(struct ast_sdp_state *sdp_state);
+
+/*!
+ * \brief Are we the SDP offerer.
+ * \since 15.0.0
+ *
+ * \param sdp_state
+ *
+ * \retval 0 if we are not the offerer.
+ * \retval non-zero we are the offerer.
+ */
+int ast_sdp_state_is_offerer(struct ast_sdp_state *sdp_state);
+
+/*!
+ * \brief Are we the SDP answerer.
+ * \since 15.0.0
+ *
+ * \param sdp_state
+ *
+ * \retval 0 if we are not the answerer.
+ * \retval non-zero we are the answerer.
+ */
+int ast_sdp_state_is_answerer(struct ast_sdp_state *sdp_state);
+
+/*!
+ * \brief Restart the SDP offer/answer negotiations.
+ *
+ * \param sdp_state
+ *
+ * \retval 0 Success
+ * \retval non-0 Failure
+ */
+int ast_sdp_state_restart_negotiations(struct ast_sdp_state *sdp_state);
+
+/*!
+ * \brief Update the local stream topology on the SDP state.
+ *
+ * \details
+ * Basically we are saving off any topology updates until we create the
+ * next SDP offer. Repeated updates merge with the previous updated
+ * topology.
+ *
+ * \param sdp_state
+ * \param topology The new stream topology.
+ *
+ * \retval 0 Success
+ * \retval non-0 Failure
+ *
+ * \since 15
+ */
+int ast_sdp_state_update_local_topology(struct ast_sdp_state *sdp_state, struct ast_stream_topology *topology);
+
+/*!
+ * \brief Set the local address (IP address) to use for connection addresses
+ *
+ * \param sdp_state
+ * \param address The local address
+ *
+ * \note
+ * Passing NULL as an address will unset the explicit local connection address.
+ *
+ * \since 15
+ */
+void ast_sdp_state_set_local_address(struct ast_sdp_state *sdp_state, struct ast_sockaddr *address);
+
+/*!
+ * \brief Set the connection address (IP address and port) to use for a specific stream
+ *
+ * \param sdp_state
+ * \param stream_index The stream to set the connection address for
+ * \param address The connection address
+ *
+ * \retval 0 Success
+ *
+ * \note
+ * Passing NULL as an address will unset the explicit local connection address.
+ *
+ * \since 15
+ */
+int ast_sdp_state_set_connection_address(struct ast_sdp_state *sdp_state, int stream_index,
+ struct ast_sockaddr *address);
+
+/*!
+ * \since 15.0.0
+ * \brief Set the global locally held state.
+ *
+ * \param sdp_state
+ * \param locally_held
+ */
+void ast_sdp_state_set_global_locally_held(struct ast_sdp_state *sdp_state, unsigned int locally_held);
+
+/*!
+ * \since 15.0.0
+ * \brief Get the global locally held state.
+ *
+ * \param sdp_state
+ *
+ * \returns locally_held
+ */
+unsigned int ast_sdp_state_get_global_locally_held(const struct ast_sdp_state *sdp_state);
+
+/*!
+ * \since 15.0.0
+ * \brief Set a stream to be held or unheld locally
+ *
+ * \param sdp_state
+ * \param stream_index The stream to set the held value for
+ * \param locally_held
+ */
+void ast_sdp_state_set_locally_held(struct ast_sdp_state *sdp_state,
+ int stream_index, unsigned int locally_held);
+
+/*!
+ * \since 15.0.0
+ * \brief Get whether a stream is locally held or not
+ *
+ * \param sdp_state
+ * \param stream_index The stream to get the held state for
+ *
+ * \returns locally_held
+ */
+unsigned int ast_sdp_state_get_locally_held(const struct ast_sdp_state *sdp_state,
+ int stream_index);
+
+/*!
+ * \since 15.0.0
+ * \brief Get whether a stream is remotely held or not
+ *
+ * \param sdp_state
+ * \param stream_index The stream to get the held state for
+ *
+ * \returns remotely_held
+ */
+unsigned int ast_sdp_state_get_remotely_held(const struct ast_sdp_state *sdp_state,
+ int stream_index);
+
+/*!
+ * \since 15.0.0
+ * \brief Set the UDPTL session parameters
+ *
+ * \param sdp_state
+ * \param stream_index The stream to set the UDPTL session parameters for
+ * \param params
*/
-struct ast_stream_topology *ast_sdp_state_get_joint_topology(struct ast_sdp_state *sdp_state);
+void ast_sdp_state_set_t38_parameters(struct ast_sdp_state *sdp_state,
+ int stream_index, struct ast_control_t38_parameters *params);
#endif /* _ASTERISK_SDP_STATE_H */
diff --git a/include/asterisk/sdp_translator.h b/include/asterisk/sdp_translator.h
index 62a875e0a..e1d51f0be 100644
--- a/include/asterisk/sdp_translator.h
+++ b/include/asterisk/sdp_translator.h
@@ -28,15 +28,15 @@ struct sdp;
*/
struct ast_sdp_translator_ops {
/*! The SDP representation on which this translator operates */
- enum ast_sdp_options_repr repr;
+ enum ast_sdp_options_impl repr;
/*! Allocate new translator private data for a translator */
void *(*translator_new)(void);
/*! Free translator private data */
void (*translator_free)(void *translator_priv);
/*! Convert the channel-native SDP into an internal Asterisk SDP */
- struct ast_sdp *(*to_sdp)(void *repr_sdp, void *translator_priv);
+ struct ast_sdp *(*to_sdp)(const void *repr_sdp, void *translator_priv);
/*! Convert an internal Asterisk SDP into a channel-native SDP */
- void *(*from_sdp)(struct ast_sdp *sdp, void *translator_priv);
+ const void *(*from_sdp)(const struct ast_sdp *sdp, void *translator_priv);
};
/*!
@@ -72,7 +72,7 @@ void ast_sdp_unregister_translator(struct ast_sdp_translator_ops *ops);
* \retval NULL FAIL
* \retval non-NULL New SDP translator
*/
-struct ast_sdp_translator *ast_sdp_translator_new(enum ast_sdp_options_repr repr);
+struct ast_sdp_translator *ast_sdp_translator_new(enum ast_sdp_options_impl repr);
/*!
* \brief Free an SDP translator
@@ -87,7 +87,7 @@ void ast_sdp_translator_free(struct ast_sdp_translator *translator);
* \retval NULL FAIL
* \retval Non-NULL The translated SDP
*/
-struct ast_sdp *ast_sdp_translator_to_sdp(struct ast_sdp_translator *translator, void *native_sdp);
+struct ast_sdp *ast_sdp_translator_to_sdp(struct ast_sdp_translator *translator, const void *native_sdp);
/*!
* \brief Translate an internal Asterisk SDP to a native SDP
@@ -97,6 +97,7 @@ struct ast_sdp *ast_sdp_translator_to_sdp(struct ast_sdp_translator *translator,
* \retval NULL FAIL
* \retval non-NULL The translated SDP
*/
-void *ast_sdp_translator_from_sdp(struct ast_sdp_translator *translator, struct ast_sdp *ast_sdp);
+const void *ast_sdp_translator_from_sdp(struct ast_sdp_translator *translator,
+ const struct ast_sdp *ast_sdp);
#endif /* _ASTERISK_SDP_TRANSLATOR_H */
diff --git a/include/asterisk/smoother.h b/include/asterisk/smoother.h
index e63aa77bd..65ac88921 100644
--- a/include/asterisk/smoother.h
+++ b/include/asterisk/smoother.h
@@ -33,6 +33,7 @@ extern "C" {
#define AST_SMOOTHER_FLAG_G729 (1 << 0)
#define AST_SMOOTHER_FLAG_BE (1 << 1)
+#define AST_SMOOTHER_FLAG_FORCED (1 << 2)
/*! \name AST_Smoother
*/
diff --git a/include/asterisk/sorcery.h b/include/asterisk/sorcery.h
index 896633816..bfb2c39ad 100644
--- a/include/asterisk/sorcery.h
+++ b/include/asterisk/sorcery.h
@@ -392,9 +392,9 @@ int ast_sorcery_wizard_unregister(const struct ast_sorcery_wizard *interface);
* \retval non-NULL success
* \retval NULL if allocation failed
*/
-struct ast_sorcery *__ast_sorcery_open(const char *module);
+struct ast_sorcery *__ast_sorcery_open(const char *module, const char *file, int line, const char *func);
-#define ast_sorcery_open() __ast_sorcery_open(AST_MODULE)
+#define ast_sorcery_open() __ast_sorcery_open(AST_MODULE, __FILE__, __LINE__, __PRETTY_FUNCTION__)
/*!
* \brief Retrieves an existing sorcery instance by module name
@@ -1280,8 +1280,13 @@ int ast_sorcery_is_stale(const struct ast_sorcery *sorcery, void *object);
* \brief Decrease the reference count of a sorcery structure
*
* \param sorcery Pointer to a sorcery structure
+ *
+ * \note Prior to 16.0.0 this was a function which had to be used.
+ * Now you can use any variant of ao2_cleanup or ao2_ref to
+ * release a reference.
*/
-void ast_sorcery_unref(struct ast_sorcery *sorcery);
+#define ast_sorcery_unref(sorcery) \
+ ao2_cleanup(sorcery)
/*!
* \brief Get the unique identifier of a sorcery object
diff --git a/include/asterisk/stasis_app.h b/include/asterisk/stasis_app.h
index e131833a9..8ef2bda1c 100644
--- a/include/asterisk/stasis_app.h
+++ b/include/asterisk/stasis_app.h
@@ -51,7 +51,6 @@
*/
#include "asterisk/channel.h"
-#include "asterisk/json.h"
/*! @{ */
@@ -794,6 +793,38 @@ int stasis_app_control_remove_channel_from_bridge(
struct stasis_app_control *control, struct ast_bridge *bridge);
/*!
+ * \brief Initialize bridge features into a channel control
+ *
+ * \note Bridge features on a control are destroyed after each bridge session,
+ * so new features need to be initialized before each bridge add.
+ *
+ * \param control Control in which to store the features
+ *
+ * \return non-zero on failure
+ * \return zero on success
+ */
+int stasis_app_control_bridge_features_init(
+ struct stasis_app_control *control);
+
+/*!
+ * \brief Set whether DTMF from the channel is absorbed instead of passing through to the bridge
+ *
+ * \param control Control whose channel should have its DTMF absorbed when bridged
+ * \param absorb Whether DTMF should be absorbed (1) instead of passed through (0).
+ */
+void stasis_app_control_absorb_dtmf_in_bridge(
+ struct stasis_app_control *control, int absorb);
+
+/*!
+ * \brief Set whether audio from the channel is muted instead of passing through to the bridge
+ *
+ * \param control Control whose channel should have its audio muted when bridged
+ * \param mute Whether audio should be muted (1) instead of passed through (0).
+ */
+void stasis_app_control_mute_in_bridge(
+ struct stasis_app_control *control, int mute);
+
+/*!
* \since 12
* \brief Gets the bridge currently associated with a control object.
*
diff --git a/include/asterisk/stasis_channels.h b/include/asterisk/stasis_channels.h
index deb79b0d0..4843617db 100644
--- a/include/asterisk/stasis_channels.h
+++ b/include/asterisk/stasis_channels.h
@@ -22,7 +22,6 @@
#include "asterisk/stringfields.h"
#include "asterisk/stasis.h"
-#include "asterisk/json.h"
#include "asterisk/channel.h"
/*! \addtogroup StasisTopicsAndMessages
diff --git a/include/asterisk/stasis_endpoints.h b/include/asterisk/stasis_endpoints.h
index 539f270cf..2fbe5f4b7 100644
--- a/include/asterisk/stasis_endpoints.h
+++ b/include/asterisk/stasis_endpoints.h
@@ -28,7 +28,6 @@
*/
#include "asterisk/endpoints.h"
-#include "asterisk/json.h"
#include "asterisk/stasis.h"
#include "asterisk/stasis_cache_pattern.h"
#include "asterisk/stringfields.h"
diff --git a/include/asterisk/stasis_system.h b/include/asterisk/stasis_system.h
index 274c02e49..55959063c 100644
--- a/include/asterisk/stasis_system.h
+++ b/include/asterisk/stasis_system.h
@@ -19,7 +19,6 @@
#ifndef _ASTERISK_STASIS_SYSTEM_H
#define _ASTERISK_STASIS_SYSTEM_H
-#include "asterisk/json.h"
#include "asterisk/stasis.h"
/*!
diff --git a/include/asterisk/stream.h b/include/asterisk/stream.h
index 48ee88322..c2d5a8877 100644
--- a/include/asterisk/stream.h
+++ b/include/asterisk/stream.h
@@ -27,6 +27,7 @@
#define _AST_STREAM_H_
#include "asterisk/codec.h"
+#include "asterisk/vector.h"
/*!
* \brief Forward declaration for a stream, as it is opaque
@@ -44,29 +45,50 @@ struct ast_format_cap;
struct ast_stream_topology;
/*!
+ * \brief A mapping of two topologies.
+ */
+struct ast_stream_topology_map;
+
+typedef void (*ast_stream_data_free_fn)(void *);
+
+/*!
* \brief States that a stream may be in
*/
enum ast_stream_state {
- /*!
- * \brief Set when the stream has been removed
- */
- AST_STREAM_STATE_REMOVED = 0,
- /*!
- * \brief Set when the stream is sending and receiving media
- */
- AST_STREAM_STATE_SENDRECV,
- /*!
- * \brief Set when the stream is sending media only
- */
- AST_STREAM_STATE_SENDONLY,
- /*!
- * \brief Set when the stream is receiving media only
- */
- AST_STREAM_STATE_RECVONLY,
- /*!
- * \brief Set when the stream is not sending OR receiving media
- */
- AST_STREAM_STATE_INACTIVE,
+ /*!
+ * \brief Set when the stream has been removed/declined
+ */
+ AST_STREAM_STATE_REMOVED = 0,
+ /*!
+ * \brief Set when the stream is sending and receiving media
+ */
+ AST_STREAM_STATE_SENDRECV,
+ /*!
+ * \brief Set when the stream is sending media only
+ */
+ AST_STREAM_STATE_SENDONLY,
+ /*!
+ * \brief Set when the stream is receiving media only
+ */
+ AST_STREAM_STATE_RECVONLY,
+ /*!
+ * \brief Set when the stream is not sending OR receiving media
+ */
+ AST_STREAM_STATE_INACTIVE,
+};
+
+/*!
+ * \brief Stream data slots
+ */
+enum ast_stream_data_slot {
+ /*!
+ * \brief Data slot for RTP instance
+ */
+ AST_STREAM_DATA_RTP_CODECS = 0,
+ /*!
+ * \brief Controls the size of the data pointer array
+ */
+ AST_STREAM_DATA_SLOT_MAX
};
/*!
@@ -99,13 +121,17 @@ void ast_stream_free(struct ast_stream *stream);
* \brief Create a deep clone of an existing stream
*
* \param stream The existing stream
+ * \param Optional name for cloned stream. If NULL, then existing stream's name is copied.
*
* \retval non-NULL success
* \retval NULL failure
*
+ * \note Opaque data pointers set with ast_stream_set_data() are not part
+ * of the deep clone. We have no way to clone the data.
+ *
* \since 15
*/
-struct ast_stream *ast_stream_clone(const struct ast_stream *stream);
+struct ast_stream *ast_stream_clone(const struct ast_stream *stream, const char *name);
/*!
* \brief Get the name of a stream
@@ -202,6 +228,45 @@ void ast_stream_set_state(struct ast_stream *stream, enum ast_stream_state state
const char *ast_stream_state2str(enum ast_stream_state state);
/*!
+ * \brief Convert a string to a stream state
+ *
+ * \param str The string to convert
+ *
+ * \return The stream state
+ *
+ * \since 15.0.0
+ */
+enum ast_stream_state ast_stream_str2state(const char *str);
+
+/*!
+ * \brief Get the opaque stream data
+ *
+ * \param stream The media stream
+ * \param slot The data slot to retrieve
+ *
+ * \retval non-NULL success
+ * \retval NULL failure
+ *
+ * \since 15
+ */
+void *ast_stream_get_data(struct ast_stream *stream, enum ast_stream_data_slot slot);
+
+/*!
+ * \brief Set the opaque stream data
+ *
+ * \param stream The media stream
+ * \param slot The data slot to set
+ * \param data Opaque data
+ * \param data_free_fn Callback to free data when stream is freed. May be NULL for no action.
+ *
+ * \return data
+ *
+ * \since 15
+ */
+void *ast_stream_set_data(struct ast_stream *stream, enum ast_stream_data_slot slot,
+ void *data, ast_stream_data_free_fn data_free_fn);
+
+/*!
* \brief Get the position of the stream in the topology
*
* \param stream The media stream
@@ -236,6 +301,20 @@ struct ast_stream_topology *ast_stream_topology_clone(
const struct ast_stream_topology *topology);
/*!
+ * \brief Compare two stream topologies to see if they are equal
+ *
+ * \param left The left topology
+ * \param right The right topology
+ *
+ * \retval 1 topologies are equivalent
+ * \retval 0 topologies differ
+ *
+ * \since 15
+ */
+int ast_stream_topology_equal(const struct ast_stream_topology *left,
+ const struct ast_stream_topology *right);
+
+/*!
* \brief Destroy a stream topology
*
* \param topology The topology of streams
@@ -305,11 +384,30 @@ int ast_stream_topology_set_stream(struct ast_stream_topology *topology,
unsigned int position, struct ast_stream *stream);
/*!
+ * \brief Delete a specified stream from the given topology.
+ * \since 15.0.0
+ *
+ * \param topology The topology of streams.
+ * \param position The topology position to delete.
+ *
+ * \note Deleting a stream will completely remove it from the topology
+ * as if it never existed in it. i.e., Any following stream positions
+ * will shift down so there is no gap.
+ *
+ * \retval 0 on success.
+ * \retval -1 on failure.
+ *
+ * \return Nothing
+ */
+int ast_stream_topology_del_stream(struct ast_stream_topology *topology,
+ unsigned int position);
+
+/*!
* \brief A helper function that, given a format capabilities structure,
* creates a topology and separates the media types in format_cap into
* separate streams.
*
- * \param caps The format capabilities structure
+ * \param caps The format capabilities structure (NULL creates an empty topology)
*
* \retval non-NULL success
* \retval NULL failure
@@ -318,7 +416,7 @@ int ast_stream_topology_set_stream(struct ast_stream_topology *topology,
* since a new format capabilities structure is created for each media type.
*
* \note Each stream will have its name set to the corresponding media type.
- * For example: "AST_MEDIA_TYPE_AUDIO".
+ * For example: "audio".
*
* \note Each stream will be set to the sendrecv state.
*
@@ -328,7 +426,26 @@ struct ast_stream_topology *ast_stream_topology_create_from_format_cap(
struct ast_format_cap *cap);
/*!
- * \brief Gets the first stream of a specific type from the topology
+ * \brief Create a format capabilities structure representing the topology.
+ *
+ * \details
+ * A helper function that, given a stream topology, creates a format
+ * capabilities structure containing all formats from all active streams.
+ *
+ * \param topology The topology of streams
+ *
+ * \retval non-NULL success
+ * \retval NULL failure
+ *
+ * \note The stream topology is NOT altered by this function.
+ *
+ * \since 15
+ */
+struct ast_format_cap *ast_format_cap_from_stream_topology(
+ struct ast_stream_topology *topology);
+
+/*!
+ * \brief Gets the first active stream of a specific type from the topology
*
* \param topology The topology of streams
* \param type The media type
@@ -342,4 +459,42 @@ struct ast_stream *ast_stream_topology_get_first_stream_by_type(
const struct ast_stream_topology *topology,
enum ast_media_type type);
+/*!
+ * \brief Map a given topology's streams to the given types.
+ *
+ * \note The given vectors in which mapping values are placed are reset by
+ * this function. This means if those vectors already contain mapping
+ * values they will be lost.
+ *
+ * \param topology The topology to map
+ * \param types The media types to be mapped
+ * \param v0 Index mapping of topology to types
+ * \param v1 Index mapping of types to topology
+ *
+ * \since 15
+ */
+void ast_stream_topology_map(const struct ast_stream_topology *topology,
+ struct ast_vector_int *types, struct ast_vector_int *v0, struct ast_vector_int *v1);
+
+/*!
+ * \brief Get the stream group that a stream is part of
+ *
+ * \param stream The stream
+ *
+ * \return the numerical stream group (-1 if not in a group)
+ *
+ * \since 15.2.0
+ */
+int ast_stream_get_group(const struct ast_stream *stream);
+
+/*!
+ * \brief Set the stream group for a stream
+ *
+ * \param stream The stream
+ * \param group The group the stream is part of
+ *
+ * \since 15.2.0
+ */
+void ast_stream_set_group(struct ast_stream *stream, int group);
+
#endif /* _AST_STREAM_H */
diff --git a/include/asterisk/strings.h b/include/asterisk/strings.h
index eb5b4e43c..963519dc7 100644
--- a/include/asterisk/strings.h
+++ b/include/asterisk/strings.h
@@ -26,6 +26,7 @@
/* #define DEBUG_OPAQUE */
#include <ctype.h>
+#include <limits.h>
#include "asterisk/utils.h"
#include "asterisk/threadstorage.h"
@@ -1174,6 +1175,19 @@ char *ast_tech_to_upper(char *dev_str),
)
/*!
+ * \brief Restrict hash value range
+ *
+ * \details
+ * Hash values used all over asterisk are expected to be non-negative
+ * (signed) int values. This function restricts an unsigned int hash
+ * value to the positive half of the (signed) int values.
+ */
+static force_inline int attribute_pure ast_str_hash_restrict(unsigned int hash)
+{
+ return (int) (hash & (unsigned int) INT_MAX);
+}
+
+/*!
* \brief Compute a hash value on a string
*
* This famous hash algorithm was written by Dan Bernstein and is
@@ -1183,20 +1197,21 @@ char *ast_tech_to_upper(char *dev_str),
*/
static force_inline int attribute_pure ast_str_hash(const char *str)
{
- int hash = 5381;
+ unsigned int hash = 5381;
- while (*str)
- hash = hash * 33 ^ *str++;
+ while (*str) {
+ hash = hash * 33 ^ (unsigned char) *str++;
+ }
- return abs(hash);
+ return ast_str_hash_restrict(hash);
}
/*!
* \brief Compute a hash value on a string
*
* \param[in] str The string to add to the hash
- * \param[in] hash The hash value to add to
- *
+ * \param[in] seed The hash value to start with
+ *
* \details
* This version of the function is for when you need to compute a
* string hash of more than one string.
@@ -1206,12 +1221,15 @@ static force_inline int attribute_pure ast_str_hash(const char *str)
*
* \sa http://www.cse.yorku.ca/~oz/hash.html
*/
-static force_inline int ast_str_hash_add(const char *str, int hash)
+static force_inline int ast_str_hash_add(const char *str, int seed)
{
- while (*str)
- hash = hash * 33 ^ *str++;
+ unsigned int hash = (unsigned int) seed;
+
+ while (*str) {
+ hash = hash * 33 ^ (unsigned char) *str++;
+ }
- return abs(hash);
+ return ast_str_hash_restrict(hash);
}
/*!
@@ -1223,13 +1241,13 @@ static force_inline int ast_str_hash_add(const char *str, int hash)
*/
static force_inline int attribute_pure ast_str_case_hash(const char *str)
{
- int hash = 5381;
+ unsigned int hash = 5381;
while (*str) {
- hash = hash * 33 ^ tolower(*str++);
+ hash = hash * 33 ^ (unsigned char) tolower(*str++);
}
- return abs(hash);
+ return ast_str_hash_restrict(hash);
}
/*!
@@ -1365,4 +1383,24 @@ char *ast_generate_random_string(char *buf, size_t size);
*/
int ast_strings_match(const char *left, const char *op, const char *right);
+/*!
+ * \brief Read lines from a string buffer
+ * \since 13.18.0
+ *
+ * \param buffer [IN/OUT] A pointer to a char * string with either Unix or Windows line endings
+ *
+ * \return The "next" line
+ *
+ * \warning The original string and *buffer will be modified.
+ *
+ * \details
+ * Both '\n' and '\r\n' are treated as single delimiters but consecutive occurrances of
+ * the delimiters are NOT considered to be a single delimiter. This preserves blank
+ * lines in the input.
+ *
+ * MacOS line endings ('\r') are not supported at this time.
+ *
+ */
+char *ast_read_line_from_buffer(char **buffer);
+
#endif /* _ASTERISK_STRINGS_H */
diff --git a/include/asterisk/test.h b/include/asterisk/test.h
index 49731feb6..90e772cbc 100644
--- a/include/asterisk/test.h
+++ b/include/asterisk/test.h
@@ -241,6 +241,14 @@ struct ast_test_info {
* \note The description must not end with a newline.
*/
const char *description;
+ /*!
+ * \brief Only run if explicitly named
+ *
+ * \details
+ * Run this test only if it's explicitly named on the command line.
+ * Do NOT run it as part of an execute category or execute all command.
+ */
+ unsigned int explicit_only;
};
#ifdef TEST_FRAMEWORK
diff --git a/include/asterisk/utils.h b/include/asterisk/utils.h
index 423d73b26..0a12b1d8a 100644
--- a/include/asterisk/utils.h
+++ b/include/asterisk/utils.h
@@ -622,7 +622,13 @@ int __ast_vasprintf(char **ret, const char *fmt, va_list ap, const char *file, i
DEBUG_CHAOS_RETURN(DEBUG_CHAOS_ALLOC_CHANCE, -1);
- if ((res = vasprintf(ret, fmt, ap)) == -1) {
+ res = vasprintf(ret, fmt, ap);
+ if (res < 0) {
+ /*
+ * *ret is undefined so set to NULL to ensure it is
+ * initialized to something useful.
+ */
+ *ret = NULL;
MALLOC_FAILURE_MSG;
}
diff --git a/include/asterisk/vector.h b/include/asterisk/vector.h
index 83732e7c8..8bd1cefef 100644
--- a/include/asterisk/vector.h
+++ b/include/asterisk/vector.h
@@ -48,6 +48,12 @@
size_t current; \
}
+/*! \brief Integer vector definition */
+AST_VECTOR(ast_vector_int, int);
+
+/*! \brief String vector definition */
+AST_VECTOR(ast_vector_string, char *);
+
/*!
* \brief Define a vector structure with a read/write lock
*
@@ -88,6 +94,26 @@
})
/*!
+ * \brief Steal the elements from a vector and reinitialize.
+ *
+ * \param vec Vector to operate on.
+ *
+ * This allows you to use vector.h to construct a list and use the
+ * data as a bare array.
+ *
+ * \note The stolen array must eventually be released using ast_free.
+ *
+ * \warning AST_VECTOR_SIZE and AST_VECTOR_MAX_SIZE are both reset
+ * to 0. If either are needed they must be saved to a local
+ * variable before stealing the elements.
+ */
+#define AST_VECTOR_STEAL_ELEMENTS(vec) ({ \
+ typeof((vec)->elems) __elems = (vec)->elems; \
+ AST_VECTOR_INIT((vec), 0); \
+ (__elems); \
+})
+
+/*!
* \brief Initialize a vector with a read/write lock
*
* If \a size is 0, then no space will be allocated until the vector is
@@ -241,6 +267,29 @@
})
/*!
+ * \brief Default a vector up to size with the given value.
+ *
+ * \note If a size of 0 is given then all elements in the given vector are set.
+ * \note The vector will grow to the given size if needed.
+ *
+ * \param vec Vector to default.
+ * \param size The number of elements to default
+ * \param value The default value to set each element to
+ */
+#define AST_VECTOR_DEFAULT(vec, size, value) ({ \
+ int res = 0; \
+ typeof((size)) __size = (size) ? (size) : AST_VECTOR_SIZE(vec); \
+ size_t idx; \
+ for (idx = 0; idx < __size; ++idx) { \
+ res = AST_VECTOR_REPLACE(vec, idx, value); \
+ if (res == -1) { \
+ break; \
+ } \
+ } \
+ res; \
+})
+
+/*!
* \brief Insert an element at a specific position in a vector, growing the vector if needed.
*
* \param vec Vector to insert into.
@@ -278,27 +327,31 @@
* \brief Add an element into a sorted vector
*
* \param vec Sorted vector to add to.
- * \param elem Element to insert.
+ * \param elem Element to insert. Must not be an array type.
* \param cmp A strcmp compatible compare function.
*
* \return 0 on success.
* \return Non-zero on failure.
*
* \warning Use of this macro on an unsorted vector will produce unpredictable results
+ * \warning 'elem' must not be an array type so passing 'x' where 'x' is defined as
+ * 'char x[4]' will fail to compile. However casting 'x' as 'char *' does
+ * result in a value that CAN be used.
*/
#define AST_VECTOR_ADD_SORTED(vec, elem, cmp) ({ \
int res = 0; \
size_t __idx = (vec)->current; \
+ typeof(elem) __elem = (elem); \
do { \
if (__make_room((vec)->current, vec) != 0) { \
res = -1; \
break; \
} \
- while (__idx > 0 && (cmp((vec)->elems[__idx - 1], elem) > 0)) { \
+ while (__idx > 0 && (cmp((vec)->elems[__idx - 1], __elem) > 0)) { \
(vec)->elems[__idx] = (vec)->elems[__idx - 1]; \
__idx--; \
} \
- (vec)->elems[__idx] = elem; \
+ (vec)->elems[__idx] = __elem; \
(vec)->current++; \
} while (0); \
res; \
@@ -518,6 +571,14 @@
#define AST_VECTOR_SIZE(vec) (vec)->current
/*!
+ * \brief Get the maximum number of elements the vector can currently hold.
+ *
+ * \param vec Vector to query.
+ * \return Maximum number of elements the vector can currently hold.
+ */
+#define AST_VECTOR_MAX_SIZE(vec) (vec)->max
+
+/*!
* \brief Reset vector.
*
* \param vec Vector to reset.
@@ -553,6 +614,42 @@
})
/*!
+ * \brief Get the nth index from a vector that matches the given comparison
+ *
+ * \param vec Vector to get from.
+ * \param nth The nth index to find
+ * \param value Value to pass into comparator.
+ * \param cmp Comparator function/macros (called as \c cmp(elem, value))
+ *
+ * \return a pointer to the element that was found or NULL
+ */
+#define AST_VECTOR_GET_INDEX_NTH(vec, nth, value, cmp) ({ \
+ int res = -1; \
+ size_t idx; \
+ typeof(nth) __nth = (nth); \
+ typeof(value) __value = (value); \
+ for (idx = 0; idx < (vec)->current; ++idx) { \
+ if (cmp((vec)->elems[idx], __value) && !(--__nth)) { \
+ res = (int)idx; \
+ break; \
+ } \
+ } \
+ res; \
+})
+
+/*!
+ * \brief Get the 1st index from a vector that matches the given comparison
+ *
+ * \param vec Vector to get from.
+ * \param value Value to pass into comparator.
+ * \param cmp Comparator function/macros (called as \c cmp(elem, value))
+ *
+ * \return a pointer to the element that was found or NULL
+ */
+#define AST_VECTOR_GET_INDEX(vec, value, cmp) \
+ AST_VECTOR_GET_INDEX_NTH(vec, 1, value, cmp)
+
+/*!
* \brief Get an element from a vector that matches the given comparison
*
* \param vec Vector to get from.
diff --git a/include/asterisk/xml.h b/include/asterisk/xml.h
index 063e8c0b3..ab7b630a2 100644
--- a/include/asterisk/xml.h
+++ b/include/asterisk/xml.h
@@ -246,10 +246,5 @@ struct ast_xml_node *ast_xml_xpath_get_first_result(struct ast_xml_xpath_results
*/
struct ast_xml_xpath_results *ast_xml_query(struct ast_xml_doc *doc, const char *xpath_str);
-/* Features using ast_xml_ */
-#ifdef HAVE_LIBXML2
-#define AST_XML_DOCS
-#endif
-
#endif /* _ASTERISK_XML_H */