[svn-commits] file: branch file/rtp_engine r127112 - in /team/file/rtp_engine: channels/ in...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Tue Jul 1 14:34:57 CDT 2008


Author: file
Date: Tue Jul  1 14:34:56 2008
New Revision: 127112

URL: http://svn.digium.com/view/asterisk?view=rev&rev=127112
Log:
Add basic API in. Moving on to making the built in RTP stack a module and filling in the gaps I have missed/overlooked.

Added:
    team/file/rtp_engine/include/asterisk/rtp_engine.h   (with props)
    team/file/rtp_engine/main/rtp_engine.c   (with props)
    team/file/rtp_engine/res/res_rtp_asterisk.c
      - copied, changed from r126519, team/file/rtp_engine/main/rtp.c
Modified:
    team/file/rtp_engine/channels/chan_sip.c
    team/file/rtp_engine/main/Makefile
    team/file/rtp_engine/main/asterisk.c
    team/file/rtp_engine/main/loader.c

Modified: team/file/rtp_engine/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/file/rtp_engine/channels/chan_sip.c?view=diff&rev=127112&r1=127111&r2=127112
==============================================================================
--- team/file/rtp_engine/channels/chan_sip.c (original)
+++ team/file/rtp_engine/channels/chan_sip.c Tue Jul  1 14:34:56 2008
@@ -196,7 +196,6 @@
 #include "asterisk/ast_version.h"
 #include "asterisk/event.h"
 #include "asterisk/tcptls.h"
-#include "asterisk/rtp_engine.h"
 #include "asterisk/stun.h"
 
 #ifndef FALSE

Added: team/file/rtp_engine/include/asterisk/rtp_engine.h
URL: http://svn.digium.com/view/asterisk/team/file/rtp_engine/include/asterisk/rtp_engine.h?view=auto&rev=127112
==============================================================================
--- team/file/rtp_engine/include/asterisk/rtp_engine.h (added)
+++ team/file/rtp_engine/include/asterisk/rtp_engine.h Tue Jul  1 14:34:56 2008
@@ -1,0 +1,238 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2008, Digium, Inc.
+ *
+ * Joshua Colp <jcolp at 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 Pluggable RTP Architecture
+ */
+
+#ifndef _ASTERISK_RTP_ENGINE_H
+#define _ASTERISK_RTP_ENGINE_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/* Maximum number of payloads supported */
+#define AST_RTP_MAX_PT 256
+
+struct ast_rtp_instance;
+struct ast_rtp_glue;
+
+enum ast_rtp_property {
+	AST_RTP_PROPERTY_NAT = 0,         /*!< Perform symmetric RTP actions */
+	AST_RTP_PROPERTY_DTMF,            /*!< RTP instance is carrying DTMF */
+	AST_RTP_PROPERTY_DTMF_COMPENSATE, /*!< Expect unreliable DTMF from remote party */
+	AST_RTP_PROPERTY_STUN,            /*!< Use STUN */
+	AST_RTP_PROPERTY_RED,             /*!< Use RED */
+	AST_RTP_PROPERTY_MAX,             /*!< Maximum number of properties supported */
+};
+
+enum ast_rtp_options {
+	AST_RTP_OPT_G726_NONSTANDARD = (1 << 0),
+};
+
+/* Codes for RTP-specific data - not defined by our AST_FORMAT codes */
+/*! DTMF (RFC2833) */
+#define AST_RTP_DTMF                    (1 << 0)
+/*! 'Comfort Noise' (RFC3389) */
+#define AST_RTP_CN                      (1 << 1)
+/*! DTMF (Cisco Proprietary) */
+#define AST_RTP_CISCO_DTMF              (1 << 2)
+/*! Maximum RTP-specific code */
+#define AST_RTP_MAX                     AST_RTP_CISCO_DTMF
+
+struct ast_rtp_payload_type {
+	int isAstFormat; /*!< Is this an Asterisk value? */
+	int code;        /*!< Actual internal value */
+};
+
+struct ast_rtp_engine {
+	const char *name;                                                                               /*!< Name of the RTP engine */
+	struct ast_module *mod;                                                                         /*!< Module this RTP engine belongs to */
+	int (*new)(struct ast_rtp_instance *instance);                                                  /*!< Callback for creating an RTP instance */
+	int (*destroy)(struct ast_rtp_instance *instance);                                              /*!< Callback for destroying an RTP instance */
+	int (*write)(struct ast_rtp_instance *instance, struct ast_frame *frame);                       /*!< Callback for writing a frame out */
+	int (*dtmf_begin)(struct ast_rtp_instance *instance, char digit);                               /*!< Callback for sending a DTMF digit */
+	int (*dtmf_end)(struct ast_rtp_instance *instance, char digit);                                 /*!< Callback for ending a DTMF digit */
+	void (*new_source)(struct ast_rtp_instance *instance);                                          /*!< Callback for when a new source of audio has come in */
+	void (*prop_set)(struct ast_rtp_instance *instance, enum ast_rtp_property property, int value); /*!< Callback for when an RTP property is set */
+	void (*payload_set)(struct ast_rtp_instance *instance, int payload, int AstFormat, int format); /*!< Callback for when a payload is set */
+	void (*packetization_set)(struct ast_rtp_instance *instance, struct ast_codec_pref *pref);      /*!< Callback for setting codec packetization preferences */
+	struct ast_frame *(*read)(struct ast_rtp_instance *instance);                                   /*!< Callback for reading a frame in */
+	AST_RWLIST_ENTRY(ast_rtp_engine) entry;                                                         /*!< Linked list information */
+};
+
+struct ast_rtp_instance {
+	struct ast_rtp_engine *engine;                        /*!< Engine handling this RTP session instance */
+	struct ast_rtp_glue *glue;                            /*!< Glue that interfaces with the channel driver */
+	void *data;                                           /*!< Unique data for the RTP engine */
+	int properties[AST_RTP_PROPERTY_MAX];                 /*!< Properties and their values */
+	struct ast_codec_pref pref;                           /*!< Codec packetization preferences */
+	struct sockaddr_in local_address;                     /*!< The address we are expecting RTP to be received on */
+	struct sockaddr_in remote_address;                    /*!< The address we are sending RTP to */
+	struct ast_rtp_payload_type payloads[AST_RTP_MAX_PT]; /*!< Payloads present */
+};
+
+struct ast_rtp_glue {
+	const char *name; /*!< Name of the channel driver this glue works with */
+};
+
+#define ast_rtp_engine_register(engine) ast_rtp_engine_register2(engine, ast_module_info->self)
+
+/*! \brief Register an RTP engine
+ *
+ * \param engine Structure of the RTP engine to register
+ * \param module Module that the RTP engine is part of
+ *
+ * \retval 0 success
+ * \retval -1 failure
+ */
+int ast_rtp_engine_register2(struct ast_rtp_engine *engine, struct ast_module *module);
+
+/*! \brief Unregister an RTP engine
+ *
+ * \param engine Structure of the RTP engine to unregister
+ *
+ * \retval 0 success
+ * \retval -1 failure
+ */
+int ast_rtp_engine_unregister(struct ast_rtp_engine *engine);
+
+/*! \brief Create a new RTP instance
+ *
+ * \param engine_name Name of the engine to use for the RTP instance
+ *
+ * \retval non-NULL success
+ * \retval NULL failure
+ */
+struct ast_rtp_instance *ast_rtp_instance_new(const char *engine_name);
+
+/*! \brief Destroy an RTP instance
+ *
+ * \param instance The RTP instance to destroy
+ *
+ * \retval 0 success
+ * \retval -1 failure
+ */
+int ast_rtp_instance_destroy(struct ast_rtp_instance *instance);
+
+/*! \brief Send a frame out over RTP
+ *
+ * \param instance The RTP instance to send frame out on
+ *
+ * \retval 0 success
+ * \retval -1 failure
+ */
+int ast_rtp_instance_write(struct ast_rtp_instance *instance, struct ast_frame *frame);
+
+/*! \brief Receive a frame over RTP
+ *
+ * \param instance The RTP instance to receive frame on
+ *
+ * \retval non-NULL success
+ * \retval NULL failure
+ */
+struct ast_frame *ast_rtp_instance_read(struct ast_rtp_instance *instance);
+
+/*! \brief Set the address of the remote endpoint that we are sending RTP to
+ *
+ * \param instance The RTP instance to change the address on
+ * \param address Address to set it to
+ *
+ * \retval 0 success
+ * \retval -1 failure
+ */
+int ast_rtp_instance_set_remote_address(struct ast_rtp_instance *instance, struct sockaddr_in *address);
+
+/*! \brief Set the value of an RTP instance property
+ *
+ * \param instance The RTP instance to set the property on
+ * \param property The property to modify
+ * \param value The value to set the property to
+ */
+void ast_rtp_instance_set_prop(struct ast_rtp_instance *instance, enum ast_rtp_property property, int value);
+
+/*! \brief Clear payload information from an RTP instance
+ *
+ * \param instance The RTP instance to clear payload information from
+ */
+void ast_rtp_instance_payloads_clear(struct ast_rtp_instance *instance);
+
+/*! \brief Set payload information on an RTP instance to the default
+ *
+ * \param instance The RTP instance to set default payload information on
+ */
+void ast_rtp_instance_payloads_default(struct ast_rtp_instance *instance);
+
+/*! \brief Copy payload information from one RTP instance to another */
+void ast_rtp_instance_payloads_copy(struct ast_rtp_instance *src, struct ast_rtp_instance *dest);
+
+/*! \brief Record payload information that was seen in an m= SDP line */
+void ast_rtp_instance_payloads_set_m_type(struct ast_rtp_instance *instance, int payload);
+
+/*! \brief Record payload information that was seen in an a=rtpmap: SDP line */
+int ast_rtp_instance_payloads_set_rtpmap_type(struct ast_rtp_instance *instance, int payload, const char *mimeType, const char *mimeSubtype, enum ast_rtp_options options);
+
+/*! \brief Remove payload information */
+void ast_rtp_instance_payloads_unset(struct ast_rtp_instance *instance, int payload);
+
+/*! \brief Retrieve payload information by payload */
+struct ast_rtp_payload_type ast_rtp_instance_payload_lookup(struct ast_rtp_instance *instance, int payload);
+
+/*! \brief Retrieve all formats that were found */
+void ast_rtp_instance_payload_formats(struct ast_rtp_instance *instance, int *AstFormats, int *nonAstFormats);
+
+/*! \brief Retrieve a payload based on whether it is an Asterisk format and the code */
+int ast_rtp_instance_payload_code(struct ast_rtp_instance *instance, const int isAstFormat, const int code);
+
+/*! \brief Retrieve mime subtype information on a payload */
+const char *ast_rtp_lookup_mime_subtype(const int isAstFormat, const int code, enum ast_rtp_options options);
+
+/*! \brief Convert formats into a string and put them into a buffer */
+char *ast_rtp_lookup_mime_multiple(char *buf, size_t size, const int capability, const int isAstFormat, enum ast_rtp_options options);
+
+/*! \brief Set codec packetization preferences */
+void ast_rtp_instance_packetization_set(struct ast_rtp_instance *instance, struct ast_codec_pref *prefs);
+
+/*! \brief Begin sending a DTMF digit
+ *
+ * \param instance The RTP instance to send the DTMF on
+ * \param digit What DTMF digit to send
+ *
+ * \retval 0 success
+ * \retval -1 failure
+ */
+int ast_rtp_instance_dtmf_begin(struct ast_rtp_instance *instance, char digit);
+
+/*! \brief Stop sending a DTMF digit
+ *
+ * \param instance The RTP instance to stop the DTMF on
+ * \param digit What DTMF digit to stop
+ * \retval 0 success
+ * \retval -1 failure
+ */
+int ast_rtp_instance_dtmf_end(struct ast_rtp_instance *instance, char digit);
+
+/*! \brief Indicate a new source of audio has dropped in */
+void ast_rtp_instance_new_source(struct ast_rtp_instance *instance);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _ASTERISK_RTP_ENGINE_H */

Propchange: team/file/rtp_engine/include/asterisk/rtp_engine.h
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: team/file/rtp_engine/include/asterisk/rtp_engine.h
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: team/file/rtp_engine/include/asterisk/rtp_engine.h
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: team/file/rtp_engine/main/Makefile
URL: http://svn.digium.com/view/asterisk/team/file/rtp_engine/main/Makefile?view=diff&rev=127112&r1=127111&r2=127112
==============================================================================
--- team/file/rtp_engine/main/Makefile (original)
+++ team/file/rtp_engine/main/Makefile Tue Jul  1 14:34:56 2008
@@ -22,7 +22,7 @@
 OBJS= tcptls.o io.o sched.o logger.o frame.o loader.o config.o channel.o \
 	translate.o file.o pbx.o cli.o md5.o term.o \
 	ulaw.o alaw.o callerid.o fskmodem.o image.o app.o \
-	cdr.o tdd.o acl.o rtp.o udptl.o manager.o asterisk.o \
+	cdr.o tdd.o acl.o udptl.o manager.o asterisk.o \
 	dsp.o chanvars.o indications.o autoservice.o db.o privacy.o \
 	astmm.o enum.o srv.o dns.o aescrypt.o aestab.o aeskey.o \
 	utils.o plc.o jitterbuf.o dnsmgr.o devicestate.o \
@@ -30,7 +30,7 @@
 	cryptostub.o sha1.o http.o fixedjitterbuf.o abstract_jb.o \
 	strcompat.o threadstorage.o dial.o event.o adsistub.o audiohook.o \
 	astobj2.o hashtab.o global_datastores.o $(RESAMPLE_OBJS) version.o \
-	features.o taskprocessor.o timing.o
+	features.o taskprocessor.o timing.o rtp_engine.o stun.o
 
 # we need to link in the objects statically, not as a library, because
 # otherwise modules will not have them available if none of the static

Modified: team/file/rtp_engine/main/asterisk.c
URL: http://svn.digium.com/view/asterisk/team/file/rtp_engine/main/asterisk.c?view=diff&rev=127112&r1=127111&r2=127112
==============================================================================
--- team/file/rtp_engine/main/asterisk.c (original)
+++ team/file/rtp_engine/main/asterisk.c Tue Jul  1 14:34:56 2008
@@ -3342,7 +3342,6 @@
 		exit(1);
 	}
 
-	ast_rtp_init();
 	ast_stun_init();
 	ast_dsp_init();
 	ast_udptl_init();

Modified: team/file/rtp_engine/main/loader.c
URL: http://svn.digium.com/view/asterisk/team/file/rtp_engine/main/loader.c?view=diff&rev=127112&r1=127111&r2=127112
==============================================================================
--- team/file/rtp_engine/main/loader.c (original)
+++ team/file/rtp_engine/main/loader.c Tue Jul  1 14:34:56 2008
@@ -247,7 +247,6 @@
 	{ "extconfig",	read_config_maps },
 	{ "enum",	ast_enum_reload },
 	{ "manager",	reload_manager },
-	{ "rtp",	ast_rtp_reload },
 	{ "http",	ast_http_reload },
 	{ "logger",	logger_reload },
 	{ "features",	ast_features_reload },

Added: team/file/rtp_engine/main/rtp_engine.c
URL: http://svn.digium.com/view/asterisk/team/file/rtp_engine/main/rtp_engine.c?view=auto&rev=127112
==============================================================================
--- team/file/rtp_engine/main/rtp_engine.c (added)
+++ team/file/rtp_engine/main/rtp_engine.c Tue Jul  1 14:34:56 2008
@@ -1,0 +1,508 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2008, Digium, Inc.
+ *
+ * Joshua Colp <jcolp at 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 Pluggable RTP Architecture
+ *
+ * \author Joshua Colp <jcolp at digium.com>
+ */
+
+#include "asterisk.h"
+
+ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
+
+#include "asterisk/channel.h"
+#include "asterisk/frame.h"
+#include "asterisk/module.h"
+#include "asterisk/rtp_engine.h"
+
+/* List of RTP engines that are currently registered */
+static AST_RWLIST_HEAD_STATIC(engines, ast_rtp_engine);
+
+/* The following array defines the MIME Media type (and subtype) for each
+   of our codecs, or RTP-specific data type. */
+static struct {
+        struct ast_rtp_payload_type payloadType;
+        char* type;
+        char* subtype;
+} mimeTypes[] = {
+        {{1, AST_FORMAT_G723_1}, "audio", "G723"},
+        {{1, AST_FORMAT_GSM}, "audio", "GSM"},
+        {{1, AST_FORMAT_ULAW}, "audio", "PCMU"},
+        {{1, AST_FORMAT_ULAW}, "audio", "G711U"},
+        {{1, AST_FORMAT_ALAW}, "audio", "PCMA"},
+        {{1, AST_FORMAT_ALAW}, "audio", "G711A"},
+        {{1, AST_FORMAT_G726}, "audio", "G726-32"},
+        {{1, AST_FORMAT_ADPCM}, "audio", "DVI4"},
+        {{1, AST_FORMAT_SLINEAR}, "audio", "L16"},
+        {{1, AST_FORMAT_LPC10}, "audio", "LPC"},
+        {{1, AST_FORMAT_G729A}, "audio", "G729"},
+        {{1, AST_FORMAT_G729A}, "audio", "G729A"},
+        {{1, AST_FORMAT_SPEEX}, "audio", "speex"},
+        {{1, AST_FORMAT_ILBC}, "audio", "iLBC"},
+        {{1, AST_FORMAT_G722}, "audio", "G722"},
+        {{1, AST_FORMAT_G726_AAL2}, "audio", "AAL2-G726-32"},
+        {{0, AST_RTP_DTMF}, "audio", "telephone-event"},
+        {{0, AST_RTP_CISCO_DTMF}, "audio", "cisco-telephone-event"},
+        {{0, AST_RTP_CN}, "audio", "CN"},
+        {{1, AST_FORMAT_JPEG}, "video", "JPEG"},
+        {{1, AST_FORMAT_PNG}, "video", "PNG"},
+        {{1, AST_FORMAT_H261}, "video", "H261"},
+        {{1, AST_FORMAT_H263}, "video", "H263"},
+        {{1, AST_FORMAT_H263_PLUS}, "video", "h263-1998"},
+        {{1, AST_FORMAT_H264}, "video", "H264"},
+        {{1, AST_FORMAT_MP4_VIDEO}, "video", "MP4V-ES"},
+        {{1, AST_FORMAT_T140RED}, "text", "RED"},
+        {{1, AST_FORMAT_T140}, "text", "T140"},
+};
+
+/*!
+ * \brief Mapping between Asterisk codecs and rtp payload types
+ *
+ * Static (i.e., well-known) RTP payload types for our "AST_FORMAT..."s:
+ * also, our own choices for dynamic payload types.  This is our master
+ * table for transmission
+ *
+ * See http://www.iana.org/assignments/rtp-parameters for a list of
+ * assigned values
+ */
+static struct ast_rtp_payload_type static_RTP_PT[AST_RTP_MAX_PT] = {
+        [0] = {1, AST_FORMAT_ULAW},
+#ifdef USE_DEPRECATED_G726
+        [2] = {1, AST_FORMAT_G726}, /* Technically this is G.721, but if Cisco can do it, so can we... */
+#endif
+        [3] = {1, AST_FORMAT_GSM},
+        [4] = {1, AST_FORMAT_G723_1},
+        [5] = {1, AST_FORMAT_ADPCM}, /* 8 kHz */
+        [6] = {1, AST_FORMAT_ADPCM}, /* 16 kHz */
+        [7] = {1, AST_FORMAT_LPC10},
+        [8] = {1, AST_FORMAT_ALAW},
+        [9] = {1, AST_FORMAT_G722},
+        [10] = {1, AST_FORMAT_SLINEAR}, /* 2 channels */
+        [11] = {1, AST_FORMAT_SLINEAR}, /* 1 channel */
+        [13] = {0, AST_RTP_CN},
+        [16] = {1, AST_FORMAT_ADPCM}, /* 11.025 kHz */
+        [17] = {1, AST_FORMAT_ADPCM}, /* 22.050 kHz */
+        [18] = {1, AST_FORMAT_G729A},
+        [19] = {0, AST_RTP_CN},         /* Also used for CN */
+        [26] = {1, AST_FORMAT_JPEG},
+        [31] = {1, AST_FORMAT_H261},
+        [34] = {1, AST_FORMAT_H263},
+        [97] = {1, AST_FORMAT_ILBC},
+        [98] = {1, AST_FORMAT_H263_PLUS},
+        [99] = {1, AST_FORMAT_H264},
+        [101] = {0, AST_RTP_DTMF},
+        [103] = {1, AST_FORMAT_H263_PLUS},
+        [104] = {1, AST_FORMAT_MP4_VIDEO},
+        [105] = {1, AST_FORMAT_T140RED},        /* Real time text chat (with redundancy encoding) */
+        [106] = {1, AST_FORMAT_T140},   /* Real time text chat */
+        [110] = {1, AST_FORMAT_SPEEX},
+        [111] = {1, AST_FORMAT_G726},
+        [112] = {1, AST_FORMAT_G726_AAL2},
+        [121] = {0, AST_RTP_CISCO_DTMF}, /* Must be type 121 */
+};
+
+int ast_rtp_engine_register2(struct ast_rtp_engine *engine, struct ast_module *module)
+{
+	struct ast_rtp_engine *current_engine;
+
+	/* Perform a sanity check on the engine structure to make sure it has the basics */
+	if (ast_strlen_zero(engine->name) || !engine->new || !engine->destroy || !engine->write || !engine->read) {
+		ast_log(LOG_WARNING, "RTP Engine '%s' failed sanity check so it was not registered.\n", !ast_strlen_zero(engine->name) ? engine->name : "Unknown");
+		return -1;
+	}
+
+	/* Link owner module to the RTP engine for reference counting purposes */
+	engine->mod = module;
+
+	AST_RWLIST_WRLOCK(&engines);
+
+	/* Ensure that no two modules with the same name are registered at the same time */
+	AST_RWLIST_TRAVERSE(&engines, current_engine, entry) {
+		if (!strcmp(current_engine->name, engine->name)) {
+			ast_log(LOG_WARNING, "An RTP engine with the name '%s' has already been registered.\n", engine->name);
+			AST_RWLIST_UNLOCK(&engines);
+			return -1;
+		}
+	}
+
+	/* The engine survived our critique. Off to the list it goes to be used */
+	AST_RWLIST_INSERT_TAIL(&engines, engine, entry);
+
+	AST_RWLIST_UNLOCK(&engines);
+
+	if (option_verbose > 1) {
+		ast_verbose(VERBOSE_PREFIX_2 "Registered RTP engine '%s'\n", engine->name);
+	}
+
+	return 0;
+}
+
+int ast_rtp_engine_unregister(struct ast_rtp_engine *engine)
+{
+	struct ast_rtp_engine *current_engine = NULL;
+
+	AST_RWLIST_WRLOCK(&engines);
+
+	/* Ensure that this engine is already registered */
+	AST_RWLIST_TRAVERSE(&engines, current_engine, entry) {
+		if (current_engine == engine) {
+			break;
+		}
+	}
+
+	if (current_engine) {
+		AST_RWLIST_REMOVE(&engines, engine, entry);
+	}
+
+	AST_RWLIST_UNLOCK(&engines);
+
+	if (current_engine && option_verbose > 1) {
+		ast_verbose(VERBOSE_PREFIX_2 "Unregistered RTP engine '%s'\n", engine->name);
+	}
+
+	return current_engine ? 0 : -1;
+}
+
+struct ast_rtp_instance *ast_rtp_instance_new(const char *engine_name)
+{
+	struct ast_rtp_instance *instance = NULL;
+	struct ast_rtp_engine *engine = NULL;
+
+	AST_RWLIST_RDLOCK(&engines);
+	
+	/* If an engine name was specified try to use it or otherwise use the first one registered */
+	if (!ast_strlen_zero(engine_name)) {
+		AST_RWLIST_TRAVERSE(&engines, engine, entry) {
+			if (!strcmp(engine->name, engine_name)) {
+				break;
+			}
+		}
+	} else {
+		engine = AST_RWLIST_FIRST(&engines);
+	}
+
+	/* If no engine was actually found bail out now */
+	if (!engine) {
+		AST_RWLIST_UNLOCK(&engines);
+		return NULL;
+	}
+
+	/* Bump up the reference count before we return so the module can not be unloaded */
+	ast_module_ref(engine->mod);
+
+	AST_RWLIST_UNLOCK(&engines);
+
+	/* Allocate a new RTP instance */
+	if (!(instance = ast_calloc(1, sizeof(*instance)))) {
+		ast_module_unref(engine->mod);
+		return NULL;
+	}
+	instance->engine = engine;
+
+	/* And pass it off to the engine to setup */
+	if (instance->engine->new(instance)) {
+		ast_module_unref(engine->mod);
+		ast_free(instance);
+		return NULL;
+	}
+
+	return instance;
+}
+
+int ast_rtp_instance_destroy(struct ast_rtp_instance *instance)
+{
+	/* Pass us off to the engine to destroy */
+	if (instance->engine->destroy(instance)) {
+		return -1;
+	}
+
+	/* Drop our engine reference */
+	ast_module_unref(instance->engine->mod);
+
+	/* and do the hand jive */
+	ast_free(instance);
+
+	return 0;
+}
+
+int ast_rtp_instance_write(struct ast_rtp_instance *instance, struct ast_frame *frame)
+{
+	return instance->engine->write(instance, frame);
+}
+
+struct ast_frame *ast_rtp_instance_read(struct ast_rtp_instance *instance)
+{
+	return instance->engine->read(instance);
+}
+
+int ast_rtp_instance_set_remote_address(struct ast_rtp_instance *instance, struct sockaddr_in *address)
+{
+	return -1;
+}
+
+void ast_rtp_instance_set_prop(struct ast_rtp_instance *instance, enum ast_rtp_property property, int value)
+{
+	instance->properties[property] = value;
+
+	if (instance->engine->prop_set) {
+		instance->engine->prop_set(instance, property, value);
+	}
+
+	return;
+}
+
+void ast_rtp_instance_payloads_clear(struct ast_rtp_instance *instance)
+{
+	int i;
+
+	for (i = 0; i < AST_RTP_MAX_PT; i++) {
+		instance->payloads[i].isAstFormat = 0;
+		instance->payloads[i].code = 0;
+		if (instance->engine && instance->engine->payload_set) {
+			instance->engine->payload_set(instance, i, 0, 0);
+		}
+	}
+
+	return;
+}
+
+void ast_rtp_instance_payloads_default(struct ast_rtp_instance *instance)
+{
+	int i;
+
+	for (i = 0; i < AST_RTP_MAX_PT; i++) {
+		instance->payloads[i].isAstFormat = static_RTP_PT[i].isAstFormat;
+		instance->payloads[i].code = static_RTP_PT[i].code;
+		if (instance->engine && instance->engine->payload_set) {
+			instance->engine->payload_set(instance, i, instance->payloads[i].isAstFormat, instance->payloads[i].code);
+		}
+	}
+
+	return;
+}
+
+void ast_rtp_instance_payloads_copy(struct ast_rtp_instance *src, struct ast_rtp_instance *dest)
+{
+	int i;
+
+	for (i = 0; i < AST_RTP_MAX_PT; i++) {
+		dest->payloads[i].isAstFormat = src->payloads[i].isAstFormat;
+		dest->payloads[i].code = src->payloads[i].code;
+		if (dest->engine && dest->engine->payload_set) {
+			dest->engine->payload_set(dest, i, dest->payloads[i].isAstFormat, dest->payloads[i].code);
+		}
+	}
+
+	return;
+}
+
+void ast_rtp_instance_payloads_set_m_type(struct ast_rtp_instance *instance, int payload)
+{
+	if (payload < 0 || payload > AST_RTP_MAX_PT || !static_RTP_PT[payload].code) {
+		return;
+	}
+
+	instance->payloads[payload] = static_RTP_PT[payload];
+
+	if (instance->engine && instance->engine->payload_set) {
+		instance->engine->payload_set(instance, payload, instance->payloads[payload].isAstFormat, instance->payloads[payload].code);
+	}
+
+	return;
+}
+
+int ast_rtp_instance_payloads_set_rtpmap_type(struct ast_rtp_instance *instance, int payload, const char *mimeType, const char *mimeSubtype, enum ast_rtp_options options)
+{
+	int i;
+
+	if (payload < 0 || payload > AST_RTP_MAX_PT) {
+		return -1;
+	}
+
+	for (i = 0; i < AST_RTP_MAX_PT; i++) {
+		if (!strcasecmp(mimeTypes[i].subtype, mimeSubtype) && !strcasecmp(mimeTypes[i].type, mimeType)) {
+			instance->payloads[i] = mimeTypes[i].payloadType;
+			if (instance->engine && instance->engine->payload_set) {
+				instance->engine->payload_set(instance, i, instance->payloads[i].isAstFormat, instance->payloads[i].code);
+			}
+			return 0;
+		}
+	}
+
+	return -1;
+}
+
+void ast_rtp_instance_payloads_unset(struct ast_rtp_instance *instance, int payload)
+{
+	if (payload < 0 || payload > AST_RTP_MAX_PT) {
+		return;
+	}
+
+	instance->payloads[payload].isAstFormat = 0;
+	instance->payloads[payload].code = 0;
+
+	if (instance->engine && instance->engine->payload_set) {
+		instance->engine->payload_set(instance, payload, 0, 0);
+	}
+
+	return;
+}
+
+struct ast_rtp_payload_type ast_rtp_instance_payload_lookup(struct ast_rtp_instance *instance, int payload)
+{
+	struct ast_rtp_payload_type result = { .isAstFormat = 0, };
+
+	if (payload < 0 || payload > AST_RTP_MAX_PT) {
+		return result;
+	}
+
+	result = instance->payloads[payload];
+
+	if (!result.code) {
+		result = static_RTP_PT[payload];
+	}
+
+	return result;
+}
+
+void ast_rtp_instance_payload_formats(struct ast_rtp_instance *instance, int *AstFormats, int *nonAstFormats)
+{
+	int i;
+
+	*AstFormats = *nonAstFormats = 0;
+
+	for (i = 0; i < AST_RTP_MAX_PT; i++) {
+		if (instance->payloads[i].isAstFormat) {
+			*AstFormats |= instance->payloads[i].code;
+		} else {
+			*nonAstFormats |= instance->payloads[i].code;
+		}
+	}
+
+	return;
+}
+
+int ast_rtp_instance_payload_code(struct ast_rtp_instance *instance, const int isAstFormat, const int code)
+{
+	int i;
+
+	for (i = 0; i < AST_RTP_MAX_PT; i++) {
+		if (instance->payloads[i].isAstFormat == isAstFormat && instance->payloads[i].code == code) {
+			return i;
+		}
+	}
+
+	for (i = 0; i < AST_RTP_MAX_PT; i++) {
+		if (static_RTP_PT[i].isAstFormat == isAstFormat && static_RTP_PT[i].code == code) {
+			return i;
+		}
+	}
+
+	return -1;
+}
+
+const char *ast_rtp_lookup_mime_subtype(const int isAstFormat, const int code, enum ast_rtp_options options)
+{
+	int i;
+	
+	for (i = 0; i < sizeof(mimeTypes) / sizeof(mimeTypes[0]); i++) {
+		if (mimeTypes[i].payloadType.code == code && mimeTypes[i].payloadType.isAstFormat == isAstFormat) {
+			if (isAstFormat && (code == AST_FORMAT_G726_AAL2) && (options & AST_RTP_OPT_G726_NONSTANDARD)) {
+				return "G726-32";
+			} else {
+				return mimeTypes[i].subtype;
+			}
+		}
+	}
+	
+	return "";
+}
+
+char *ast_rtp_lookup_mime_multiple(char *buf, size_t size, const int capability, const int isAstFormat, enum ast_rtp_options options)
+{
+	int format;
+	unsigned len;
+	char *end = buf, *start = buf;
+
+	if (!buf || !size) {
+		return NULL;
+	}
+
+	snprintf(end, size, "0x%x (", capability);
+	
+	len = strlen(end);
+	end += len;
+	size -= len;
+	start = end;
+	
+	for (format = 1; format < AST_RTP_MAX; format <<= 1) {
+		if (capability & format) {
+			const char *name = ast_rtp_lookup_mime_subtype(isAstFormat, format, options);
+			
+			snprintf(end, size, "%s|", name);
+			len = strlen(end);
+			end += len;
+			size -= len;
+		}
+	}
+	
+	if (start == end) {
+		ast_copy_string(start, "nothing)", size);
+	} else if (size > 1) {
+		*(end -1) = ')';
+	}
+	
+	return buf;
+}
+
+void ast_rtp_instance_packetization_set(struct ast_rtp_instance *instance, struct ast_codec_pref *prefs)
+{
+	int i;
+
+	for (i = 0; i < 32; i++) {
+		instance->pref.order[i] = prefs->order[i];
+		instance->pref.framing[i] = prefs->framing[i];
+	}
+
+	if (instance->engine->packetization_set) {
+		instance->engine->packetization_set(instance, &instance->pref);
+	}
+
+	return;
+}
+
+int ast_rtp_instance_dtmf_begin(struct ast_rtp_instance *instance, char digit)
+{
+	return instance->engine->dtmf_begin ? instance->engine->dtmf_begin(instance, digit) : -1;
+}
+
+int ast_rtp_instance_dtmf_end(struct ast_rtp_instance *instance, char digit)
+{
+	return instance->engine->dtmf_end ? instance->engine->dtmf_end(instance, digit) : -1;
+}
+
+void ast_rtp_instance_new_source(struct ast_rtp_instance *instance)
+{
+	if (instance->engine->new_source) {
+		instance->engine->new_source(instance);
+	}
+
+	return;
+}

Propchange: team/file/rtp_engine/main/rtp_engine.c
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: team/file/rtp_engine/main/rtp_engine.c
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: team/file/rtp_engine/main/rtp_engine.c
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Copied: team/file/rtp_engine/res/res_rtp_asterisk.c (from r126519, team/file/rtp_engine/main/rtp.c)
URL: http://svn.digium.com/view/asterisk/team/file/rtp_engine/res/res_rtp_asterisk.c?view=diff&rev=127112&p1=team/file/rtp_engine/main/rtp.c&r1=126519&p2=team/file/rtp_engine/res/res_rtp_asterisk.c&r2=127112
==============================================================================
--- team/file/rtp_engine/main/rtp.c (original)
+++ team/file/rtp_engine/res/res_rtp_asterisk.c Tue Jul  1 14:34:56 2008
@@ -1,7 +1,7 @@
 /*
  * Asterisk -- An open source telephony toolkit.
  *
- * Copyright (C) 1999 - 2006, Digium, Inc.
+ * Copyright (C) 1999 - 2008, Digium, Inc.
  *
  * Mark Spencer <markster at digium.com>
  *
@@ -35,7 +35,7 @@
 #include <fcntl.h>
 #include <math.h> 
 
-#include "asterisk/rtp.h"
+#include "asterisk/rtp_engine.h"
 #include "asterisk/stun.h"
 #include "asterisk/pbx.h"
 #include "asterisk/frame.h"




More information about the svn-commits mailing list