summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorMatthew Jordan <mjordan@digium.com>2013-07-05 17:33:33 +0000
committerMatthew Jordan <mjordan@digium.com>2013-07-05 17:33:33 +0000
commitd0a55fa52dcc29f2db3e22549c9c2f2e68cada56 (patch)
treeb3d339dcfa5611a7be0e12b99131d21d206719a3 /include
parentd789681eaff813affe6f88f33813aebcc99d8b6a (diff)
Refactor RTCP events over to Stasis; associate with channels
This patch does the following: * It merges Jaco Kroon's patch from ASTERISK-20754, which provides channel information in the RTCP events. Because Stasis provides a cache, Jaco's patch was modified to pass the channel uniqueid to the RTP layer as opposed to a pointer to the channel. This has the following benefits: (1) It keeps the RTP engine 'clean' of references back to channels (2) It prevents circular dependencies and other potential ref counting issues * The RTP engine now allows any RTP implementation to raise RTCP messages. Potentially, other implementations (such as res_rtp_multicast) could also raise RTCP information. The engine provides structs to represent RTCP headers and RTCP SR/RR reports. * Some general refactoring in res_rtp_asterisk was done to try and tame the RTCP code. It isn't perfect - that's *way* beyond the scope of this work - but it does feel marginally better. * A few random bugs were fixed in the RTCP statistics. (Example: performing an assignment of a = a is probably not correct) * We now raise RTCP events for each SR/RR sent/received. Previously we wouldn't raise an event when we sent a RR report. Note that this work will be of use to others who want to monitor call quality or build modules that report call quality statistics. Since the events are now moving across the Stasis message bus, this is far easier to accomplish. It is also a first step (though by no means the last step) towards getting Olle's pinefrog work incorporated. Again: note that the patch by Jaco Kroon was modified slightly for this work; however, he did all of the hard work in finding the right places to set the channel in the RTP engine across the channel drivers. Much thanks goes to Jaco for his hard work here. Review: https://reviewboard.asterisk.org/r/2603/ (closes issue ASTERISK-20574) Reported by: Jaco Kroon patches: asterisk-rtcp-channel.patch uploaded by jkroon (License 5671) (closes issue ASTERISK-21471) Reported by: Matt Jordan git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@393740 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'include')
-rw-r--r--include/asterisk/cdr.h7
-rw-r--r--include/asterisk/channel.h6
-rw-r--r--include/asterisk/json.h28
-rw-r--r--include/asterisk/rtp_engine.h160
4 files changed, 176 insertions, 25 deletions
diff --git a/include/asterisk/cdr.h b/include/asterisk/cdr.h
index 9d1f6d72d..cd0501f06 100644
--- a/include/asterisk/cdr.h
+++ b/include/asterisk/cdr.h
@@ -330,11 +330,10 @@ struct ast_cdr {
char peeraccount[AST_MAX_ACCOUNT_CODE];
/*! flags */
unsigned int flags;
- /*! Unique Channel Identifier
- * 150 = 127 (max systemname) + "-" + 10 (epoch timestamp) + "." + 10 (monotonically incrementing integer) + NULL */
- char uniqueid[150];
+ /*! Unique Channel Identifier */
+ char uniqueid[AST_MAX_UNIQUEID];
/* Linked group Identifier */
- char linkedid[32];
+ char linkedid[AST_MAX_UNIQUEID];
/*! User field */
char userfield[AST_MAX_USER_FIELD];
/*! Sequence field */
diff --git a/include/asterisk/channel.h b/include/asterisk/channel.h
index 2e7468418..0f5549108 100644
--- a/include/asterisk/channel.h
+++ b/include/asterisk/channel.h
@@ -133,6 +133,12 @@ extern "C" {
#define AST_MAX_EXTENSION 80 /*!< Max length of an extension */
#define AST_MAX_CONTEXT 80 /*!< Max length of a context */
+#define AST_MAX_UNIQUEID 150 /*!< Max length of a channel uniqueid */
+/* 150 = 127 (max systemname) + "-" + 10 (epoch
+ * timestamp) + "." + 10 (monotonically incrementing
+ * integer) + NULL. Note that if this value is ever
+ * changed, MAX_CHANNEL_ID should be updated in
+ * rtp_engine.h */
#define AST_MAX_ACCOUNT_CODE 20 /*!< Max length of an account code */
#define AST_CHANNEL_NAME 80 /*!< Max length of an ast_channel name */
#define MAX_LANGUAGE 40 /*!< Max length of the language setting */
diff --git a/include/asterisk/json.h b/include/asterisk/json.h
index 0584c99af..a735fd36b 100644
--- a/include/asterisk/json.h
+++ b/include/asterisk/json.h
@@ -330,6 +330,34 @@ intmax_t ast_json_integer_get(const struct ast_json *integer);
*/
int ast_json_integer_set(struct ast_json *integer, intmax_t value);
+/*!
+ * \brief Create a JSON real number.
+ * \since 12.0.0
+ * \param value Value of the new JSON real number.
+ * \return Newly allocated real number.
+ * \return \c NULL on error.
+ */
+struct ast_json *ast_json_real_create(double value);
+
+/*!
+ * \brief Get the value from a JSON real number.
+ * \since 12.0.0
+ * \param real JSON real number.
+ * \return Value of a JSON real number.
+ * \return 0 if \a real is not a JSON real number.
+ */
+double ast_json_real_get(const struct ast_json *real);
+
+/*!
+ * \brief Set the value of a JSON real number.
+ * \since 12.0.0
+ * \param integer JSON real number to modify.
+ * \param value New value for \a real.
+ * \return 0 on success.
+ * \return -1 on error.
+ */
+int ast_json_real_set(struct ast_json *real, double value);
+
/*!@}*/
/*!@{*/
diff --git a/include/asterisk/rtp_engine.h b/include/asterisk/rtp_engine.h
index e2567f508..bda13e891 100644
--- a/include/asterisk/rtp_engine.h
+++ b/include/asterisk/rtp_engine.h
@@ -74,6 +74,7 @@ extern "C" {
#include "asterisk/netsock2.h"
#include "asterisk/sched.h"
#include "asterisk/res_srtp.h"
+#include "asterisk/stasis.h"
/* Maximum number of payloads supported */
#if defined(LOW_MEMORY)
@@ -85,6 +86,12 @@ extern "C" {
/* Maximum number of generations */
#define AST_RED_MAX_GENERATION 5
+/* Maximum size of an Asterisk channel unique ID. Should match AST_MAX_UNIQUEID.
+ * Note that we don't use that defined value directly here to avoid a hard dependency
+ * on channel.h
+ */
+#define MAX_CHANNEL_ID 150
+
struct ast_rtp_instance;
struct ast_rtp_glue;
@@ -215,6 +222,8 @@ enum ast_rtp_instance_stat {
AST_RTP_INSTANCE_STAT_LOCAL_SSRC,
/*! Retrieve remote SSRC */
AST_RTP_INSTANCE_STAT_REMOTE_SSRC,
+ /*! Retrieve channel unique ID */
+ AST_RTP_INSTANCE_STAT_CHANNEL_UNIQUEID,
};
/* Codes for RTP-specific data - not defined by our AST_FORMAT codes */
@@ -240,6 +249,46 @@ struct ast_rtp_payload_type {
int payload;
};
+/* Common RTCP report types */
+/*! Sender Report */
+#define AST_RTP_RTCP_SR 200
+/*! Receiver Report */
+#define AST_RTP_RTCP_RR 201
+
+/*!
+ * \since 12
+ * \brief A report block within a SR/RR report */
+struct ast_rtp_rtcp_report_block {
+ unsigned int source_ssrc; /*< The SSRC of the source for this report block */
+ struct {
+ unsigned short fraction; /*< The fraction of packets lost since last SR/RR */
+ unsigned int packets; /*< The cumulative packets since the beginning */
+ } lost_count; /*< Statistics regarding missed packets */
+ unsigned int highest_seq_no; /*< Extended highest sequence number received */
+ unsigned int ia_jitter; /*< Calculated interarrival jitter */
+ unsigned int lsr; /*< The time the last SR report was received */
+ unsigned int dlsr; /*< Delay in sending this report */
+};
+
+/*!
+ * \since 12
+ * \brief An object that represents data sent during a SR/RR RTCP report */
+struct ast_rtp_rtcp_report {
+ unsigned short reception_report_count; /*< The number of report blocks */
+ unsigned int ssrc; /*< Our SSRC */
+ unsigned int type; /*< The type of report. 200=SR; 201=RR */
+ struct {
+ struct timeval ntp_timestamp; /*< Our NTP timestamp */
+ unsigned int rtp_timestamp; /*< Our last RTP timestamp */
+ unsigned int packet_count; /*< Number of packets sent */
+ unsigned int octet_count; /*< Number of bytes sent */
+ } sender_information; /*< Sender information for SR */
+ /*! A dynamic array of report blocks. The number of elements is given by
+ * \c reception_report_count.
+ */
+ struct ast_rtp_rtcp_report_block *report_block[0];
+};
+
/*! Structure that represents statistics from an RTP instance */
struct ast_rtp_instance_stats {
/*! Number of packets transmitted */
@@ -300,6 +349,8 @@ struct ast_rtp_instance_stats {
unsigned int local_ssrc;
/*! Their SSRC */
unsigned int remote_ssrc;
+ /*! The Asterisk channel's unique ID that owns this instance */
+ char channel_uniqueid[MAX_CHANNEL_ID];
};
#define AST_RTP_STAT_SET(current_stat, combined, placement, value) \
@@ -310,6 +361,14 @@ return 0; \
} \
}
+#define AST_RTP_STAT_STRCPY(current_stat, combined, placement, value) \
+if (stat == current_stat || stat == AST_RTP_INSTANCE_STAT_ALL || (combined >= 0 && combined == current_stat)) { \
+ ast_copy_string(placement, value, sizeof(placement)); \
+ if (stat == current_stat) { \
+ return 0; \
+ } \
+}
+
#define AST_RTP_STAT_TERMINATOR(combined) \
if (stat == combined) { \
return 0; \
@@ -1541,6 +1600,30 @@ int ast_rtp_instance_fd(struct ast_rtp_instance *instance, int rtcp);
struct ast_rtp_glue *ast_rtp_instance_get_glue(const char *type);
/*!
+ * \brief Get the unique ID of the channel that owns this RTP instance
+ *
+ * Note that this should remain valid for the lifetime of the RTP instance.
+ *
+ * \param instance The RTP instance
+ *
+ * \retval The unique ID of the channel
+ * \retval Empty string if no channel owns this RTP instance
+ *
+ * \since 12
+ */
+const char *ast_rtp_instance_get_channel_id(struct ast_rtp_instance *instance);
+
+/*!
+ * \brief Set the channel that owns this RTP instance
+ *
+ * \param instance The RTP instance
+ * \param uniqueid The uniqueid of the channel
+ *
+ * \since 12
+ */
+void ast_rtp_instance_set_channel_id(struct ast_rtp_instance *instance, const char *uniqueid);
+
+/*!
* \brief Get the other RTP instance that an instance is bridged to
*
* \param instance The RTP instance that we want
@@ -1965,27 +2048,6 @@ struct ast_rtp_engine *ast_rtp_instance_get_engine(struct ast_rtp_instance *inst
struct ast_rtp_glue *ast_rtp_instance_get_active_glue(struct ast_rtp_instance *instance);
/*!
- * \brief Get the channel that is associated with an RTP instance while in a bridge
- *
- * \param instance The RTP instance
- *
- * \retval pointer to the channel
- *
- * Example:
- *
- * \code
- * struct ast_channel *chan = ast_rtp_instance_get_chan(instance);
- * \endcode
- *
- * This gets the channel associated with the RTP instance pointed to by 'instance'.
- *
- * \note This will only return a channel while in a local or remote bridge.
- *
- * \since 1.8
- */
-struct ast_channel *ast_rtp_instance_get_chan(struct ast_rtp_instance *instance);
-
-/*!
* \brief Send a comfort noise packet to the RTP instance
*
* \param instance The RTP instance
@@ -2073,6 +2135,62 @@ void ast_rtp_dtls_cfg_copy(const struct ast_rtp_dtls_cfg *src_cfg, struct ast_rt
*/
void ast_rtp_dtls_cfg_free(struct ast_rtp_dtls_cfg *dtls_cfg);
+struct ast_json;
+
+/*!
+ * \brief Allocate an ao2 ref counted instance of \ref ast_rtp_rtcp_report
+ *
+ * \param report_blocks The number of report blocks to allocate
+ * \retval An ao2 ref counted \ref ast_rtp_rtcp_report object on success
+ * \retval NULL on error
+ */
+struct ast_rtp_rtcp_report *ast_rtp_rtcp_report_alloc(unsigned int report_blocks);
+
+/*!
+ * \since 12
+ * \brief Publish an RTCP message to \ref stasis
+ *
+ * \param rtp The rtp instance object
+ * \param message_type The RTP message type to publish
+ * \param report The RTCP report object to publish. This should be an ao2 ref counted
+ * object. This routine will increase the reference count of the object.
+ * \param blob Additional JSON objects to publish along with the RTCP information
+ */
+void ast_rtp_publish_rtcp_message(struct ast_rtp_instance *rtp,
+ struct stasis_message_type *message_type,
+ struct ast_rtp_rtcp_report *report,
+ struct ast_json *blob);
+
+/*! \addtogroup StasisTopicsAndMessages
+ * @{
+ */
+
+/*!
+ * \since 12
+ * \brief Message type for an RTCP message sent from this Asterisk instance
+ *
+ * \retval A stasis message type
+ */
+struct stasis_message_type *ast_rtp_rtcp_sent_type(void);
+
+/*!
+ * \since 12
+ * \brief Message type for an RTCP message received from some external source
+ *
+ * \retval A stasis message type
+ */
+struct stasis_message_type *ast_rtp_rtcp_received_type(void);
+
+/*!
+ * \since 12
+ * \brief \ref stasis topic for RTP and RTCP related messages
+ *
+ * \retval A \ref stasis topic
+ */
+struct stasis_topic *ast_rtp_topic(void);
+
+/* }@ */
+
#if defined(__cplusplus) || defined(c_plusplus)
}
#endif