[asterisk-commits] kharwell: branch kharwell/pimp_sip_video r383744 - in /team/kharwell/pimp_sip...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Mon Mar 25 12:44:46 CDT 2013


Author: kharwell
Date: Mon Mar 25 12:44:41 2013
New Revision: 383744

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=383744
Log:
Fixed merge conflicts

Added:
    team/kharwell/pimp_sip_video/res/res_sip/config_domain_aliases.c
      - copied unchanged from r383743, team/group/pimp_my_sip/res/res_sip/config_domain_aliases.c
Modified:
    team/kharwell/pimp_sip_video/   (props changed)
    team/kharwell/pimp_sip_video/CHANGES
    team/kharwell/pimp_sip_video/channels/chan_gulp.c
    team/kharwell/pimp_sip_video/contrib/scripts/install_prereq
    team/kharwell/pimp_sip_video/include/asterisk/autoconfig.h.in
    team/kharwell/pimp_sip_video/include/asterisk/channel.h
    team/kharwell/pimp_sip_video/include/asterisk/res_sip.h
    team/kharwell/pimp_sip_video/include/asterisk/res_sip_session.h
    team/kharwell/pimp_sip_video/main/channel.c
    team/kharwell/pimp_sip_video/main/channel_internal_api.c
    team/kharwell/pimp_sip_video/main/manager.c
    team/kharwell/pimp_sip_video/main/manager_channels.c
    team/kharwell/pimp_sip_video/res/res_sip/sip_configuration.c
    team/kharwell/pimp_sip_video/res/res_sip_sdp_audio.c
    team/kharwell/pimp_sip_video/res/res_sip_session.c
    team/kharwell/pimp_sip_video/res/res_sip_session.exports.in

Propchange: team/kharwell/pimp_sip_video/
------------------------------------------------------------------------------
    svn:mergeinfo = /team/group/pimp_my_sip:383711-383743

Propchange: team/kharwell/pimp_sip_video/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Mon Mar 25 12:44:41 2013
@@ -1,1 +1,1 @@
-/trunk:1-383671
+/trunk:1-383729

Modified: team/kharwell/pimp_sip_video/CHANGES
URL: http://svnview.digium.com/svn/asterisk/team/kharwell/pimp_sip_video/CHANGES?view=diff&rev=383744&r1=383743&r2=383744
==============================================================================
--- team/kharwell/pimp_sip_video/CHANGES (original)
+++ team/kharwell/pimp_sip_video/CHANGES Mon Mar 25 12:44:41 2013
@@ -49,6 +49,9 @@
 
  * The AMI event 'UserEvent' from app_userevent now contains the channel state
    fields. The channel state fields will come before the body fields.
+
+ * The deprecated use of | (pipe) as a separator in the channelvars setting in
+   manager.conf has been removed.
 
 Channel Drivers
 ------------------

Modified: team/kharwell/pimp_sip_video/channels/chan_gulp.c
URL: http://svnview.digium.com/svn/asterisk/team/kharwell/pimp_sip_video/channels/chan_gulp.c?view=diff&rev=383744&r1=383743&r2=383744
==============================================================================
--- team/kharwell/pimp_sip_video/channels/chan_gulp.c (original)
+++ team/kharwell/pimp_sip_video/channels/chan_gulp.c Mon Mar 25 12:44:41 2013
@@ -146,6 +146,7 @@
 };
 
 /*! \brief SIP session interaction functions */
+static void gulp_session_begin(struct ast_sip_session *session);
 static void gulp_session_end(struct ast_sip_session *session);
 static int gulp_incoming_request(struct ast_sip_session *session, struct pjsip_rx_data *rdata);
 static void gulp_incoming_response(struct ast_sip_session *session, struct pjsip_rx_data *rdata);
@@ -153,9 +154,17 @@
 /*! \brief SIP session supplement structure */
 static struct ast_sip_session_supplement gulp_supplement = {
 	.method = "INVITE",
+	.session_begin = gulp_session_begin,
 	.session_end = gulp_session_end,
 	.incoming_request = gulp_incoming_request,
 	.incoming_response = gulp_incoming_response,
+};
+
+static int gulp_incoming_ack(struct ast_sip_session *session, struct pjsip_rx_data *rdata);
+
+static struct ast_sip_session_supplement gulp_ack_supplement = {
+	.method = "ACK",
+	.incoming_request = gulp_incoming_ack,
 };
 
 /*! \brief Dialplan function for constructing a dial string for calling all contacts */
@@ -240,14 +249,22 @@
 static enum ast_rtp_glue_result gulp_get_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance **instance)
 {
 	struct gulp_pvt *pvt = ast_channel_tech_pvt(chan);
+	struct ast_sip_endpoint *endpoint;
 
 	if (!pvt || !pvt->session || !pvt->media[SIP_MEDIA_AUDIO]->rtp) {
 		return AST_RTP_GLUE_RESULT_FORBID;
 	}
 
+	endpoint = pvt->session->endpoint;
+
 	*instance = pvt->media[SIP_MEDIA_AUDIO]->rtp;
 	ao2_ref(*instance, +1);
 
+	ast_assert(endpoint != NULL);
+	if (endpoint->direct_media) {
+		return AST_RTP_GLUE_RESULT_REMOTE;
+	}
+
 	return AST_RTP_GLUE_RESULT_LOCAL;
 }
 
@@ -269,12 +286,113 @@
 /*! \brief Function called by RTP engine to get peer capabilities */
 static void gulp_get_codec(struct ast_channel *chan, struct ast_format_cap *result)
 {
+	struct gulp_pvt *pvt = ast_channel_tech_pvt(chan);
+	ast_format_cap_copy(result, pvt->session->endpoint->codecs);
+}
+
+static int send_direct_media_request(void *data)
+{
+	RAII_VAR(struct ast_sip_session *, session, data, ao2_cleanup);
+	return ast_sip_session_refresh(session, NULL, NULL, session->endpoint->direct_media_method, 1);
+}
+
+static struct ast_datastore_info direct_media_mitigation_info = { };
+
+static int direct_media_mitigate_glare(struct ast_sip_session *session)
+{
+	RAII_VAR(struct ast_datastore *, datastore, NULL, ao2_cleanup);
+
+	if (session->endpoint->direct_media_glare_mitigation == 
+			AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_NONE) {
+		return 0;
+	}
+
+	datastore = ast_sip_session_get_datastore(session, "direct_media_mitigation");
+	if (!datastore) {
+		return 0;
+	}
+
+	/* Removing the datastore ensures we won't try to mitigate glare on subsequent reinvites */
+	ast_sip_session_remove_datastore(session, "direct_media_mitigation");
+
+	if ((session->endpoint->direct_media_glare_mitigation ==
+			AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_OUTGOING &&
+			session->inv_session->role == PJSIP_ROLE_UAC) ||
+			(session->endpoint->direct_media_glare_mitigation ==
+			AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_INCOMING &&
+			session->inv_session->role == PJSIP_ROLE_UAS)) {
+		return 1;
+	}
+
+	return 0;
+}
+
+static int check_for_rtp_changes(struct ast_channel *chan, struct ast_rtp_instance *rtp,
+		struct ast_sip_session_media *media, int rtcp_fd)
+{
+	int changed = 0;
+
+	if (rtp) {
+		changed = ast_rtp_instance_get_and_cmp_remote_address(rtp, &media->direct_media_addr);
+		if (media->rtp) {
+			ast_channel_set_fd(chan, rtcp_fd, -1);
+			ast_rtp_instance_set_prop(media->rtp, AST_RTP_PROPERTY_RTCP, 0);
+		}
+	} else if (!ast_sockaddr_isnull(&media->direct_media_addr)){
+		ast_sockaddr_setnull(&media->direct_media_addr);
+		changed = 1;
+		if (media->rtp) {
+			ast_rtp_instance_set_prop(media->rtp, AST_RTP_PROPERTY_RTCP, 1);
+			ast_channel_set_fd(chan, rtcp_fd, ast_rtp_instance_fd(media->rtp, 1));
+		}
+	}
+
+	return changed;
 }
 
 /*! \brief Function called by RTP engine to change where the remote party should send media */
-static int gulp_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance *rtp, struct ast_rtp_instance *vrtp, struct ast_rtp_instance *tpeer, const struct ast_format_cap *cap, int nat_active)
-{
-	return -1;
+static int gulp_set_rtp_peer(struct ast_channel *chan,
+		struct ast_rtp_instance *rtp,
+		struct ast_rtp_instance *vrtp,
+		struct ast_rtp_instance *tpeer,
+		const struct ast_format_cap *cap,
+		int nat_active)
+{
+	struct gulp_pvt *pvt = ast_channel_tech_pvt(chan);
+	struct ast_sip_session *session = pvt->session;
+	int changed = 0;
+
+	/* Don't try to do any direct media shenanigans on early bridges */
+	if ((rtp || vrtp || tpeer) && !ast_bridged_channel(chan)) {
+		return 0;
+	}
+
+	if (nat_active && session->endpoint->disable_direct_media_on_nat) {
+		return 0;
+	}
+
+	if (pvt->media[SIP_MEDIA_AUDIO]) {
+		changed |= check_for_rtp_changes(chan, rtp, pvt->media[SIP_MEDIA_AUDIO], 1);
+	}
+	if (pvt->media[SIP_MEDIA_VIDEO]) {
+		changed |= check_for_rtp_changes(chan, vrtp, pvt->media[SIP_MEDIA_VIDEO], 3);
+	}
+
+	if (direct_media_mitigate_glare(session)) {
+		return 0;
+	}
+
+	if (cap && !ast_format_cap_is_empty(cap) && !ast_format_cap_identical(session->direct_media_cap, cap)) {
+		ast_format_cap_copy(session->direct_media_cap, cap);
+		changed = 1;
+	}
+
+	if (changed) {
+		ao2_ref(session, +1);
+		ast_sip_push_task(session->serializer, send_direct_media_request, session);
+	}
+
+	return 0;
 }
 
 /*! \brief Local glue for interacting with the RTP engine core */
@@ -1045,6 +1163,25 @@
 	return 0;
 }
 
+static void gulp_session_begin(struct ast_sip_session *session)
+{
+	RAII_VAR(struct ast_datastore *, datastore, NULL, ao2_cleanup);
+
+	if (session->endpoint->direct_media_glare_mitigation ==
+			AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_NONE) {
+		return;
+	}
+
+	datastore = ast_sip_session_alloc_datastore(&direct_media_mitigation_info,
+			"direct_media_glare_mitigation");
+
+	if (!datastore) {
+		return;
+	}
+
+	ast_sip_session_add_datastore(session, datastore);
+}
+
 /*! \brief Function called when the session ends */
 static void gulp_session_end(struct ast_sip_session *session)
 {
@@ -1067,7 +1204,6 @@
 	pjsip_tx_data *packet = NULL;
 	int res = AST_PBX_FAILED;
 
-	/* We only care about new sessions */
 	if (session->channel) {
 		return 0;
 	}
@@ -1130,6 +1266,16 @@
 	default:
 		break;
 	}
+}
+
+static int gulp_incoming_ack(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
+{
+	if (rdata->msg_info.msg->line.req.method.id == PJSIP_ACK_METHOD) {
+		if (session->endpoint->direct_media) {
+			ast_queue_control(session->channel, AST_CONTROL_SRCCHANGE);
+		}
+	}
+	return 0;
 }
 
 /*!
@@ -1167,6 +1313,12 @@
 		goto end;
 	}
 
+	if (ast_sip_session_register_supplement(&gulp_ack_supplement)) {
+		ast_log(LOG_ERROR, "Unable to register Gulp ACK supplement\n");
+		ast_sip_session_unregister_supplement(&gulp_supplement);
+		goto end;
+	}
+
 	return 0;
 
 end:

Modified: team/kharwell/pimp_sip_video/contrib/scripts/install_prereq
URL: http://svnview.digium.com/svn/asterisk/team/kharwell/pimp_sip_video/contrib/scripts/install_prereq?view=diff&rev=383744&r1=383743&r2=383744
==============================================================================
--- team/kharwell/pimp_sip_video/contrib/scripts/install_prereq (original)
+++ team/kharwell/pimp_sip_video/contrib/scripts/install_prereq Mon Mar 25 12:44:41 2013
@@ -32,6 +32,7 @@
 PACKAGES_RH="$PACKAGES_RH spandsp-devel freetds-devel net-snmp-devel iksemel-devel corosynclib-devel newt-devel popt-devel libtool-ltdl-devel lua-devel"
 PACKAGES_RH="$PACKAGES_RH libsqlite3x-devel radiusclient-ng-devel portaudio-devel postgresql-devel libresample-devel neon-devel libical-devel"
 PACKAGES_RH="$PACKAGES_RH openldap-devel gmime22-devel sqlite2-devel mysql-devel bluez-libs-devel jack-audio-connection-kit-devel gsm-devel libedit-devel libuuid-devel"
+PACKAGES_RH="$PACKAGES_RH jansson-devel"
 
 PACKAGES_OBSD="popt gmake wget libxml libogg libvorbis curl iksemel spandsp speex iodbc freetds-0.63p1-msdblib mysql-client gmime sqlite sqlite3 jack"
 

Modified: team/kharwell/pimp_sip_video/include/asterisk/autoconfig.h.in
URL: http://svnview.digium.com/svn/asterisk/team/kharwell/pimp_sip_video/include/asterisk/autoconfig.h.in?view=diff&rev=383744&r1=383743&r2=383744
==============================================================================
--- team/kharwell/pimp_sip_video/include/asterisk/autoconfig.h.in (original)
+++ team/kharwell/pimp_sip_video/include/asterisk/autoconfig.h.in Mon Mar 25 12:44:41 2013
@@ -294,7 +294,7 @@
 /* Define if your system has the GLOB_NOMAGIC headers. */
 #undef HAVE_GLOB_NOMAGIC
 
-/* Define if your system has the GMIME libraries. */
+/* Define to 1 if you have the GMime library. */
 #undef HAVE_GMIME
 
 /* Define to indicate the GSM library */
@@ -306,7 +306,7 @@
 /* Define to indicate that gsm.h has no prefix for its location */
 #undef HAVE_GSM_HEADER
 
-/* Define if your system has the GTK2 libraries. */
+/* Define to 1 if you have the gtk2 library. */
 #undef HAVE_GTK2
 
 /* Define to 1 if you have the Hoard Memory Allocator library. */
@@ -324,7 +324,7 @@
 /* Define to 1 if you have the Iksemel Jabber library. */
 #undef HAVE_IKSEMEL
 
-/* Define if your system has the ILBC libraries. */
+/* Define to 1 if you have the System iLBC library. */
 #undef HAVE_ILBC
 
 /* Define if your system has the UW IMAP Toolkit c-client library. */
@@ -376,7 +376,7 @@
 /* Define to 1 if you have the OpenLDAP library. */
 #undef HAVE_LDAP
 
-/* Define if your system has the LIBEDIT libraries. */
+/* Define to 1 if you have the NetBSD Editline library library. */
 #undef HAVE_LIBEDIT
 
 /* Define to 1 if you have the <libintl.h> header file. */
@@ -551,7 +551,7 @@
 /* Define to indicate presence of the pg_encoding_to_char API. */
 #undef HAVE_PGSQL_pg_encoding_to_char
 
-/* Define if your system has the PJPROJECT libraries. */
+/* Define to 1 if you have the PJPROJECT library. */
 #undef HAVE_PJPROJECT
 
 /* Define to 1 if your system defines IP_PKTINFO. */
@@ -854,19 +854,19 @@
 /* Define to 1 if you have the `strtoq' function. */
 #undef HAVE_STRTOQ
 
-/* Define to 1 if `ifr_ifru.ifru_hwaddr' is a member of `struct ifreq'. */
+/* Define to 1 if `ifr_ifru.ifru_hwaddr' is member of `struct ifreq'. */
 #undef HAVE_STRUCT_IFREQ_IFR_IFRU_IFRU_HWADDR
 
-/* Define to 1 if `uid' is a member of `struct sockpeercred'. */
+/* Define to 1 if `uid' is member of `struct sockpeercred'. */
 #undef HAVE_STRUCT_SOCKPEERCRED_UID
 
-/* Define to 1 if `st_blksize' is a member of `struct stat'. */
+/* Define to 1 if `st_blksize' is member of `struct stat'. */
 #undef HAVE_STRUCT_STAT_ST_BLKSIZE
 
-/* Define to 1 if `cr_uid' is a member of `struct ucred'. */
+/* Define to 1 if `cr_uid' is member of `struct ucred'. */
 #undef HAVE_STRUCT_UCRED_CR_UID
 
-/* Define to 1 if `uid' is a member of `struct ucred'. */
+/* Define to 1 if `uid' is member of `struct ucred'. */
 #undef HAVE_STRUCT_UCRED_UID
 
 /* Define to 1 if you have the mISDN Supplemental Services library. */
@@ -1144,11 +1144,11 @@
 /* Define to the one symbol short name of this package. */
 #undef PACKAGE_TARNAME
 
-/* Define to the home page for this package. */
-#undef PACKAGE_URL
-
 /* Define to the version of this package. */
 #undef PACKAGE_VERSION
+
+/* Define to 1 if the C compiler supports function prototypes. */
+#undef PROTOTYPES
 
 /* Define to necessary symbol if this constant uses a non-standard name on
    your system. */
@@ -1168,6 +1168,11 @@
 
 /* Define to the type of arg 5 for `select'. */
 #undef SELECT_TYPE_ARG5
+
+/* Define to 1 if the `setvbuf' function takes the buffering type as its
+   second argument and the buffer pointer as the third, as on System V before
+   release 3. */
+#undef SETVBUF_REVERSED
 
 /* The size of `char *', as computed by sizeof. */
 #undef SIZEOF_CHAR_P
@@ -1204,49 +1209,53 @@
 /* Define to a type of the same size as fd_set.fds_bits[[0]] */
 #undef TYPEOF_FD_SET_FDS_BITS
 
-/* Enable extensions on AIX 3, Interix.  */
+/* Define to 1 if on AIX 3.
+   System headers sometimes define this.
+   We just want to avoid a redefinition error message.  */
 #ifndef _ALL_SOURCE
 # undef _ALL_SOURCE
 #endif
+
+/* Define to 1 if running on Darwin. */
+#undef _DARWIN_UNLIMITED_SELECT
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+#undef _FILE_OFFSET_BITS
+
 /* Enable GNU extensions on systems that have them.  */
 #ifndef _GNU_SOURCE
 # undef _GNU_SOURCE
 #endif
-/* Enable threading extensions on Solaris.  */
+
+/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */
+#undef _LARGEFILE_SOURCE
+
+/* Define for large files, on AIX-style hosts. */
+#undef _LARGE_FILES
+
+/* Define to 1 if on MINIX. */
+#undef _MINIX
+
+/* Define to 2 if the system does not provide POSIX.1 features except with
+   this defined. */
+#undef _POSIX_1_SOURCE
+
+/* Define to 1 if you need to in order for `stat' and other things to work. */
+#undef _POSIX_SOURCE
+
+/* Enable extensions on Solaris.  */
+#ifndef __EXTENSIONS__
+# undef __EXTENSIONS__
+#endif
 #ifndef _POSIX_PTHREAD_SEMANTICS
 # undef _POSIX_PTHREAD_SEMANTICS
 #endif
-/* Enable extensions on HP NonStop.  */
 #ifndef _TANDEM_SOURCE
 # undef _TANDEM_SOURCE
 #endif
-/* Enable general extensions on Solaris.  */
-#ifndef __EXTENSIONS__
-# undef __EXTENSIONS__
-#endif
-
-
-/* Define to 1 if running on Darwin. */
-#undef _DARWIN_UNLIMITED_SELECT
-
-/* Number of bits in a file offset, on hosts where this is settable. */
-#undef _FILE_OFFSET_BITS
-
-/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */
-#undef _LARGEFILE_SOURCE
-
-/* Define for large files, on AIX-style hosts. */
-#undef _LARGE_FILES
-
-/* Define to 1 if on MINIX. */
-#undef _MINIX
-
-/* Define to 2 if the system does not provide POSIX.1 features except with
-   this defined. */
-#undef _POSIX_1_SOURCE
-
-/* Define to 1 if you need to in order for `stat' and other things to work. */
-#undef _POSIX_SOURCE
+
+/* Define like PROTOTYPES; this can be used by system headers. */
+#undef __PROTOTYPES
 
 /* Define to empty if `const' does not conform to ANSI C. */
 #undef const

Modified: team/kharwell/pimp_sip_video/include/asterisk/channel.h
URL: http://svnview.digium.com/svn/asterisk/team/kharwell/pimp_sip_video/include/asterisk/channel.h?view=diff&rev=383744&r1=383743&r2=383744
==============================================================================
--- team/kharwell/pimp_sip_video/include/asterisk/channel.h (original)
+++ team/kharwell/pimp_sip_video/include/asterisk/channel.h Mon Mar 25 12:44:41 2013
@@ -4136,7 +4136,11 @@
 	int priority;			/*!< Dialplan: Current extension priority */
 	int amaflags;			/*!< AMA flags for billing */
 	int hangupcause;		/*!< Why is the channel hanged up. See causes.h */
+	int caller_pres;		/*!< Caller ID presentation. */
+
 	struct ast_flags flags;		/*!< channel flags of AST_FLAG_ type */
+
+	struct varshead *manager_vars;	/*!< Variables to be appended to manager events */
 };
 
 /*!
@@ -4153,6 +4157,27 @@
 
 /*!
  * \since 12
+ * \brief Sets the variables to be stored in the \a manager_vars field of all
+ * snapshots.
+ * \param varc Number of variable names.
+ * \param vars Array of variable names.
+ */
+void ast_channel_set_manager_vars(size_t varc, char **vars);
+
+/*!
+ * \since 12
+ * \brief Gets the variables for a given channel, as specified by ast_channel_set_manager_vars().
+ *
+ * The returned variable list is an AO2 object, so ao2_cleanup() to free it.
+ *
+ * \param chan Channel to get variables for.
+ * \return List of channel variables.
+ * \return \c NULL on error
+ */
+struct varshead *ast_channel_get_manager_vars(struct ast_channel *chan);
+
+/*!
+ * \since 12
  * \brief Message type for \ref ast_channel_snapshot.
  *
  * \retval Message type for \ref ast_channel_snapshot.
@@ -4163,10 +4188,12 @@
  * \since 12
  * \brief A topic which publishes the events for a particular channel.
  *
- * \param chan Channel.
+ * If the given \a chan is \c NULL, ast_channel_topic_all() is returned.
+ *
+ * \param chan Channel, or \c NULL.
  *
  * \retval Topic for channel's events.
- * \retval \c NULL if \a chan is \c NULL.
+ * \retval ast_channel_topic_all() if \a chan is \c NULL.
  */
 struct stasis_topic *ast_channel_topic(struct ast_channel *chan);
 

Modified: team/kharwell/pimp_sip_video/include/asterisk/res_sip.h
URL: http://svnview.digium.com/svn/asterisk/team/kharwell/pimp_sip_video/include/asterisk/res_sip.h?view=diff&rev=383744&r1=383743&r2=383744
==============================================================================
--- team/kharwell/pimp_sip_video/include/asterisk/res_sip.h (original)
+++ team/kharwell/pimp_sip_video/include/asterisk/res_sip.h Mon Mar 25 12:44:41 2013
@@ -227,6 +227,26 @@
 	AST_SIP_ENDPOINT_IDENTIFY_BY_USERNAME = (1 << 0),
 	/*! Identify based on source location of the SIP message */
 	AST_SIP_ENDPOINT_IDENTIFY_BY_LOCATION = (1 << 1),
+};
+
+enum ast_sip_session_refresh_method {
+	/*! Use reinvite to negotiate direct media */
+	AST_SIP_SESSION_REFRESH_METHOD_INVITE,
+	/*! Use UPDATE to negotiate direct media */
+	AST_SIP_SESSION_REFRESH_METHOD_UPDATE,
+};
+
+enum ast_sip_direct_media_glare_mitigation {
+	/*! Take no special action to mitigate reinvite glare */
+	AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_NONE,
+	/*! Do not send an initial direct media session refresh on outgoing call legs
+	 * Subsequent session refreshes will be sent no matter the session direction
+	 */
+	AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_OUTGOING,
+	/*! Do not send an initial direct media session refresh on incoming call legs
+	 * Subsequent session refreshes will be sent no matter the session direction
+	 */
+	AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_INCOMING,
 };
 
 /*!
@@ -288,6 +308,14 @@
 	unsigned int qualify_frequency;
 	/*! Method(s) by which the endpoint should be identified. */
 	enum ast_sip_endpoint_identifier_type ident_method;
+	/*! Boolean indicating if direct_media is permissible */
+	unsigned int direct_media;
+	/*! When using direct media, which method should be used */
+	enum ast_sip_session_refresh_method direct_media_method;
+	/*! Take steps to mitigate glare for direct media */
+	enum ast_sip_direct_media_glare_mitigation direct_media_glare_mitigation;
+	/*! Do not attempt direct media session refreshes if a media NAT is detected */
+	unsigned int disable_direct_media_on_nat;
 };
 
 /*!

Modified: team/kharwell/pimp_sip_video/include/asterisk/res_sip_session.h
URL: http://svnview.digium.com/svn/asterisk/team/kharwell/pimp_sip_video/include/asterisk/res_sip_session.h?view=diff&rev=383744&r1=383743&r2=383744
==============================================================================
--- team/kharwell/pimp_sip_video/include/asterisk/res_sip_session.h (original)
+++ team/kharwell/pimp_sip_video/include/asterisk/res_sip_session.h Mon Mar 25 12:44:41 2013
@@ -19,9 +19,13 @@
 #ifndef _RES_SIP_SESSION_H
 #define _RES_SIP_SESSION_H
 
+/* Needed for pj_timer_entry definition */
+#include "pjlib.h"
 #include "asterisk/linkedlists.h"
 /* Needed for AST_MAX_EXTENSION constant */
 #include "asterisk/channel.h"
+/* Needed for ast_sockaddr struct */
+#include "asterisk/netsock.h"
 
 /* Forward declarations */
 struct ast_sip_endpoint;
@@ -46,6 +50,8 @@
 struct ast_sip_session_media {
 	/*! \brief RTP instance itself */
 	struct ast_rtp_instance *rtp;
+	/*! \brief Direct media address */
+	struct ast_sockaddr direct_media_addr;
 	/*! \brief SDP handler that setup the RTP */
 	struct ast_sip_session_sdp_handler *handler;
 	/*! \brief Stream is on hold */
@@ -53,6 +59,12 @@
 	/*! \brief Stream type this session media handles */
 	char stream_type[1];
 };
+
+/*!
+ * \brief Opaque structure representing a request that could not be sent
+ * due to an outstanding INVITE transaction
+ */
+struct ast_sip_session_delayed_request;
 
 /*!
  * \brief A structure describing a SIP session
@@ -79,9 +91,18 @@
 	struct ao2_container *media;
 	/* Serializer for tasks relating to this SIP session */
 	struct ast_taskprocessor *serializer;
-	/* Capabilities */
+	/* Requests that could not be sent due to current inv_session state */
+	AST_LIST_HEAD_NOLOCK(, ast_sip_session_delayed_request) delayed_requests;
+	/* When we need to reschedule a reinvite, we use this structure to do it */
+	pj_timer_entry rescheduled_reinvite;
+	/* Format capabilities pertaining to direct media */
+	struct ast_format_cap *direct_media_cap;
+	/* Requested capabilities */
 	struct ast_format_cap *caps;
 };
+
+typedef int (*ast_sip_session_request_creation_cb)(struct ast_sip_session *session, pjsip_tx_data *tdata);
+typedef int (*ast_sip_session_response_cb)(struct ast_sip_session *session, pjsip_rx_data *rdata);
 
 /*!
  * \brief A supplement to SIP message processing
@@ -247,7 +268,7 @@
  * \param endpoint The endpoint that this session uses for settings
  * \param location Optional name of the location to call, be it named location or explicit URI
  * \param request_user Optional request user to place in the request URI if permitted
- * \param caps The negotiated capabilities
+ * \param caps The reqested capabilities
  */
 struct ast_sip_session *ast_sip_session_create_outgoing(struct ast_sip_endpoint *endpoint, const char *location, const char *request_user, struct ast_format_cap *caps);
 
@@ -368,18 +389,29 @@
 int ast_sip_session_get_identity(struct pjsip_rx_data *rdata, struct ast_party_id *id);
 
 /*!
- * \brief Send a reinvite on a session
+ * \brief Send a reinvite or UPDATE on a session
  *
  * This method will inspect the session in order to construct an appropriate
- * reinvite. As with any outgoing request in res_sip_session, this will
- * call into registered supplements in case they wish to add anything.
+ * session refresh request. As with any outgoing request in res_sip_session,
+ * this will call into registered supplements in case they wish to add anything.
+ *
+ * Note: The on_request_creation callback may or may not be called in the same
+ * thread where this function is called. Request creation may need to be delayed
+ * due to the current INVITE transaction state.
  * 
  * \param session The session on which the reinvite will be sent
- * \param response_cb Optional callback that can be called when the reinvite response is received. The callback is identical in nature to the incoming_response() callback for session supplements.
- * \retval 0 Successfully sent reinvite
- * \retval -1 Failure to send reinvite
- */
-int ast_sip_session_send_reinvite(struct ast_sip_session *session, int (*response_cb)(struct ast_sip_session *session, struct pjsip_rx_data *rdata));
+ * \param on_request_creation Callback called when request is created
+ * \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
+ * \retval 0 Successfully sent refresh
+ * \retval -1 Failure to send refresh
+ */
+int ast_sip_session_refresh(struct ast_sip_session *session,
+		ast_sip_session_request_creation_cb on_request_creation,
+		ast_sip_session_response_cb on_response,
+		enum ast_sip_session_refresh_method method,
+		int generate_new_sdp);
 
 /*!
  * \brief Send a SIP response
@@ -403,4 +435,18 @@
  */
 void ast_sip_session_send_request(struct ast_sip_session *session, pjsip_tx_data *tdata);
 
+/*!
+ * \brief Send a SIP request and get called back when a response is received
+ *
+ * This will send the request out exactly the same as ast_sip_send_request() does.
+ * The difference is that when a response arrives, the specified callback will be
+ * called into
+ *
+ * \param session The session on which to send the request
+ * \param tdata The request to send
+ * \param on_response Callback to be called when a response is received
+ */
+void ast_sip_session_send_request_with_cb(struct ast_sip_session *session, pjsip_tx_data *tdata,
+		ast_sip_session_response_cb on_response);
+
 #endif /* _RES_SIP_SESSION_H */

Modified: team/kharwell/pimp_sip_video/main/channel.c
URL: http://svnview.digium.com/svn/asterisk/team/kharwell/pimp_sip_video/main/channel.c?view=diff&rev=383744&r1=383743&r2=383744
==============================================================================
--- team/kharwell/pimp_sip_video/main/channel.c (original)
+++ team/kharwell/pimp_sip_video/main/channel.c Mon Mar 25 12:44:41 2013
@@ -243,6 +243,18 @@
 	stasis_publish(ast_channel_topic(chan), message);
 }
 
+static void publish_channel_blob(struct ast_channel *chan, struct ast_json *blob)
+{
+	RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
+	if (blob) {
+		message = ast_channel_blob_create(chan, blob);
+	}
+	if (message) {
+		stasis_publish(ast_channel_topic(chan), message);
+	}
+}
+
+
 static void channel_blob_dtor(void *obj)
 {
 	struct ast_channel_blob *event = obj;
@@ -309,22 +321,7 @@
 			     "type", "varset",
 			     "variable", name,
 			     "value", value);
-	if (!blob) {
-		ast_log(LOG_ERROR, "Error creating message\n");
-		return;
-	}
-
-	msg = ast_channel_blob_create(chan, ast_json_ref(blob));
-
-	if (!msg) {
-		return;
-	}
-
-	if (chan) {
-		stasis_publish(ast_channel_topic(chan), msg);
-	} else {
-		stasis_publish(ast_channel_topic_all(), msg);
-	}
+	publish_channel_blob(chan, blob);
 }
 
 
@@ -1463,22 +1460,16 @@
 /*! \brief Queue a hangup frame for channel */
 int ast_queue_hangup(struct ast_channel *chan)
 {
+	RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
+	RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
 	struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = AST_CONTROL_HANGUP };
 	int res;
 
 	/* Yeah, let's not change a lock-critical value without locking */
 	ast_channel_lock(chan);
 	ast_channel_softhangup_internal_flag_add(chan, AST_SOFTHANGUP_DEV);
-	/*** DOCUMENTATION
-		<managerEventInstance>
-			<synopsis>Raised when a hangup is requested with no set cause.</synopsis>
-		</managerEventInstance>
-	***/
-	manager_event(EVENT_FLAG_CALL, "HangupRequest",
-		"Channel: %s\r\n"
-		"Uniqueid: %s\r\n",
-		ast_channel_name(chan),
-		ast_channel_uniqueid(chan));
+	blob = ast_json_pack("{s: s}", "type", "hangup_request");
+	publish_channel_blob(chan, blob);
 
 	res = ast_queue_frame(chan, &f);
 	ast_channel_unlock(chan);
@@ -1488,6 +1479,8 @@
 /*! \brief Queue a hangup frame for channel */
 int ast_queue_hangup_with_cause(struct ast_channel *chan, int cause)
 {
+	RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
+	RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
 	struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = AST_CONTROL_HANGUP };
 	int res;
 
@@ -1501,21 +1494,10 @@
 	if (cause < 0) {
 		f.data.uint32 = ast_channel_hangupcause(chan);
 	}
-	/*** DOCUMENTATION
-		<managerEventInstance>
-			<synopsis>Raised when a hangup is requested with a specific cause code.</synopsis>
-				<syntax>
-					<xi:include xpointer="xpointer(/docs/managerEvent[@name='Hangup']/managerEventInstance/syntax/parameter[@name='Cause'])" />
-				</syntax>
-		</managerEventInstance>
-	***/
-	manager_event(EVENT_FLAG_CALL, "HangupRequest",
-		"Channel: %s\r\n"
-		"Uniqueid: %s\r\n"
-		"Cause: %d\r\n",
-		ast_channel_name(chan),
-		ast_channel_uniqueid(chan),
-		cause);
+	blob = ast_json_pack("{s: s, s: i}",
+			     "type", "hangup_request",
+			     "cause", cause);
+	publish_channel_blob(chan, blob);
 
 	res = ast_queue_frame(chan, &f);
 	ast_channel_unlock(chan);
@@ -2818,25 +2800,16 @@
 /*! \brief Softly hangup a channel, lock */
 int ast_softhangup(struct ast_channel *chan, int cause)
 {
+	RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
 	int res;
 
 	ast_channel_lock(chan);
 	res = ast_softhangup_nolock(chan, cause);
-	/*** DOCUMENTATION
-		<managerEventInstance>
-			<synopsis>Raised when a soft hangup is requested with a specific cause code.</synopsis>
-				<syntax>
-					<xi:include xpointer="xpointer(/docs/managerEvent[@name='Hangup']/managerEventInstance/syntax/parameter[@name='Cause'])" />
-				</syntax>
-		</managerEventInstance>
-	***/
-	manager_event(EVENT_FLAG_CALL, "SoftHangupRequest",
-		"Channel: %s\r\n"
-		"Uniqueid: %s\r\n"
-		"Cause: %d\r\n",
-		ast_channel_name(chan),
-		ast_channel_uniqueid(chan),
-		cause);
+	blob = ast_json_pack("{s: s, s: i, s: b}",
+			     "type", "hangup_request",
+			     "cause", cause,
+			     "soft", 1);
+	publish_channel_blob(chan, blob);
 	ast_channel_unlock(chan);
 
 	return res;
@@ -6837,39 +6810,6 @@
 }
 
 /*!
- * \pre chan is locked
- */
-static void report_new_callerid(struct ast_channel *chan)
-{
-	int pres;
-
-	pres = ast_party_id_presentation(&ast_channel_caller(chan)->id);
-	/*** DOCUMENTATION
-		<managerEventInstance>
-			<synopsis>Raised when a channel receives new Caller ID information.</synopsis>
-			<syntax>
-				<parameter name="CID-CallingPres">
-					<para>A description of the Caller ID presentation.</para>
-				</parameter>
-			</syntax>
-		</managerEventInstance>
-	***/
-	ast_manager_event(chan, EVENT_FLAG_CALL, "NewCallerid",
-		"Channel: %s\r\n"
-		"CallerIDNum: %s\r\n"
-		"CallerIDName: %s\r\n"
-		"Uniqueid: %s\r\n"
-		"CID-CallingPres: %d (%s)\r\n",
-		ast_channel_name(chan),
-		S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, ""),
-		S_COR(ast_channel_caller(chan)->id.name.valid, ast_channel_caller(chan)->id.name.str, ""),
-		ast_channel_uniqueid(chan),
-		pres,
-		ast_describe_caller_presentation(pres)
-		);
-}
-
-/*!
  * \internal
  * \brief Transfer COLP between target and transferee channels.
  * \since 1.8
@@ -7273,7 +7213,7 @@
 	ast_channel_redirecting_set(original, ast_channel_redirecting(clonechan));
 	ast_channel_redirecting_set(clonechan, &exchange.redirecting);
 
-	report_new_callerid(original);
+	publish_channel_state(original);
 
 	/* Restore original timing file descriptor */
 	ast_channel_set_fd(original, AST_TIMING_FD, ast_channel_timingfd(original));
@@ -7439,7 +7379,7 @@
 		ast_cdr_setcid(ast_channel_cdr(chan), chan);
 	}
 
-	report_new_callerid(chan);
+	publish_channel_state(chan);
 
 	ast_channel_unlock(chan);
 }
@@ -7458,26 +7398,14 @@
 
 void ast_channel_set_caller_event(struct ast_channel *chan, const struct ast_party_caller *caller, const struct ast_set_party_caller *update)
 {
-	const char *pre_set_number;
-	const char *pre_set_name;
-
 	if (ast_channel_caller(chan) == caller) {
 		/* Don't set to self */
 		return;
 	}
 
 	ast_channel_lock(chan);
-	pre_set_number =
-		S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL);
-	pre_set_name = S_COR(ast_channel_caller(chan)->id.name.valid, ast_channel_caller(chan)->id.name.str, NULL);
 	ast_party_caller_set(ast_channel_caller(chan), caller, update);
-	if (S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL)
-			!= pre_set_number
-		|| S_COR(ast_channel_caller(chan)->id.name.valid, ast_channel_caller(chan)->id.name.str, NULL)
-			!= pre_set_name) {
-		/* The caller id name or number changed. */
-		report_new_callerid(chan);
-	}
+	publish_channel_state(chan);
 	if (ast_channel_cdr(chan)) {
 		ast_cdr_setcid(ast_channel_cdr(chan), chan);
 	}
@@ -8671,8 +8599,108 @@
 	prnt(where, "%s", ast_channel_name(chan));
 }
 
+/*!
+ * \brief List of channel variables to append to all channel-related events.
+ */
+struct manager_channel_variable {
+	AST_LIST_ENTRY(manager_channel_variable) entry;
+	unsigned int isfunc:1;
+	char name[];
+};
+
+static AST_RWLIST_HEAD_STATIC(channelvars, manager_channel_variable);
+
+static void free_channelvars(void)
+{
+	struct manager_channel_variable *var;
+	AST_RWLIST_WRLOCK(&channelvars);
+	while ((var = AST_RWLIST_REMOVE_HEAD(&channelvars, entry))) {
+		ast_free(var);
+	}
+	AST_RWLIST_UNLOCK(&channelvars);
+}
+
+void ast_channel_set_manager_vars(size_t varc, char **vars)
+{
+	size_t i;
+
+	free_channelvars();
+	AST_RWLIST_WRLOCK(&channelvars);
+	for (i = 0; i < varc; ++i) {
+		const char *var = vars[i];
+		struct manager_channel_variable *mcv;
+		if (!(mcv = ast_calloc(1, sizeof(*mcv) + strlen(var) + 1))) {
+			break;
+		}
+		strcpy(mcv->name, var); /* SAFE */
+		if (strchr(var, '(')) {
+			mcv->isfunc = 1;
+		}
+		AST_RWLIST_INSERT_TAIL(&channelvars, mcv, entry);
+	}
+	AST_RWLIST_UNLOCK(&channelvars);
+}
+
+/*!
+ * \brief Destructor for the return value from ast_channel_get_manager_vars().
+ * \param obj AO2 object.
+ */
+static void varshead_dtor(void *obj)
+{
+	struct varshead *head = obj;
+	struct ast_var_t *var;
+
+	while ((var = AST_RWLIST_REMOVE_HEAD(head, entries))) {
+		ast_var_delete(var);
+	}
+}
+
+struct varshead *ast_channel_get_manager_vars(struct ast_channel *chan)
+{
+	RAII_VAR(struct varshead *, ret, NULL, ao2_cleanup);
+	RAII_VAR(struct ast_str *, tmp, NULL, ast_free);
+	struct manager_channel_variable *mcv;
+
+	ret = ao2_alloc(sizeof(*ret), varshead_dtor);
+	tmp = ast_str_create(16);
+
+	if (!ret || !tmp) {
+		return NULL;
+	}
+
+	AST_RWLIST_RDLOCK(&channelvars);
+	AST_LIST_TRAVERSE(&channelvars, mcv, entry) {
+		const char *val = NULL;
+		struct ast_var_t *var;
+
+		if (mcv->isfunc) {
+			if (ast_func_read2(chan, mcv->name, &tmp, 0) == 0) {
+				val = ast_str_buffer(tmp);
+			} else {
+				ast_log(LOG_ERROR,
+					"Error invoking function %s\n", mcv->name);
+			}
+		} else {
+			val = pbx_builtin_getvar_helper(chan, mcv->name);
+		}
+
+		var = ast_var_assign(mcv->name, val ? val : "");
+		if (!var) {
+			AST_RWLIST_UNLOCK(&channelvars);
+			return NULL;
+		}
+
+		AST_RWLIST_INSERT_TAIL(ret, var, entries);
+	}
+	AST_RWLIST_UNLOCK(&channelvars);
+
+	ao2_ref(ret, +1);
+	return ret;
+}
+
 static void channels_shutdown(void)
 {
+	free_channelvars();
 	ao2_cleanup(__channel_snapshot);
 	__channel_snapshot = NULL;
 	ao2_cleanup(__channel_blob);
@@ -11298,6 +11326,7 @@
 {
 	struct ast_channel_snapshot *snapshot = obj;
 	ast_string_field_free_memory(snapshot);
+	ao2_cleanup(snapshot->manager_vars);
 }
 
 struct ast_channel_snapshot *ast_channel_snapshot_create(struct ast_channel *chan)
@@ -11342,6 +11371,9 @@
 	snapshot->amaflags = ast_channel_amaflags(chan);
 	snapshot->hangupcause = ast_channel_hangupcause(chan);
 	snapshot->flags = *ast_channel_flags(chan);
+	snapshot->caller_pres = ast_party_id_presentation(&ast_channel_caller(chan)->id);
+
+	snapshot->manager_vars = ast_channel_get_manager_vars(chan);
 
 	ao2_ref(snapshot, +1);
 	return snapshot;

Modified: team/kharwell/pimp_sip_video/main/channel_internal_api.c
URL: http://svnview.digium.com/svn/asterisk/team/kharwell/pimp_sip_video/main/channel_internal_api.c?view=diff&rev=383744&r1=383743&r2=383744
==============================================================================
--- team/kharwell/pimp_sip_video/main/channel_internal_api.c (original)
+++ team/kharwell/pimp_sip_video/main/channel_internal_api.c Mon Mar 25 12:44:41 2013
@@ -1385,7 +1385,7 @@
 
 struct stasis_topic *ast_channel_topic(struct ast_channel *chan)
 {
-	return chan->topic;
+	return chan ? chan->topic : ast_channel_topic_all();
 }
 
 void ast_channel_internal_setup_topics(struct ast_channel *chan)

Modified: team/kharwell/pimp_sip_video/main/manager.c
URL: http://svnview.digium.com/svn/asterisk/team/kharwell/pimp_sip_video/main/manager.c?view=diff&rev=383744&r1=383743&r2=383744
==============================================================================
--- team/kharwell/pimp_sip_video/main/manager.c (original)
+++ team/kharwell/pimp_sip_video/main/manager.c Mon Mar 25 12:44:41 2013
@@ -1041,6 +1041,8 @@
 static struct ast_event_sub *acl_change_event_subscription;
 
 #define MGR_SHOW_TERMINAL_WIDTH 80
+
+#define MAX_VARS 128
 
 /*! \brief
  * Descriptor for a manager session, either on the AMI socket or over HTTP.
@@ -1167,14 +1169,6 @@
 
 static struct ao2_container *sessions = NULL;
 
-struct manager_channel_variable {
-	AST_LIST_ENTRY(manager_channel_variable) entry;
-	unsigned int isfunc:1;
-	char name[0]; /* allocate off the end the real size. */
-};
-
-static AST_RWLIST_HEAD_STATIC(channelvars, manager_channel_variable);
-
 /*! \brief user descriptor, as read from the config file.
  *
  * \note It is still missing some fields -- e.g. we can have multiple permit and deny
@@ -1208,8 +1202,6 @@
 
 /*! \brief A container of event documentation nodes */
 AO2_GLOBAL_OBJ_STATIC(event_docs);
-
-static void free_channelvars(void);
 
 static enum add_filter_result manager_add_filter(const char *filter_pattern, struct ao2_container *whitefilters, struct ao2_container *blackfilters);
 
@@ -5650,30 +5642,16 @@
 	return 0;
 }
 
-AST_THREADSTORAGE(manager_event_funcbuf);
-
 static void append_channel_vars(struct ast_str **pbuf, struct ast_channel *chan)
 {
-	struct manager_channel_variable *var;
-
-	AST_RWLIST_RDLOCK(&channelvars);
-	AST_LIST_TRAVERSE(&channelvars, var, entry) {
-		const char *val;
-		struct ast_str *res;
-
-		if (var->isfunc) {
-			res = ast_str_thread_get(&manager_event_funcbuf, 16);
-			if (res && ast_func_read2(chan, var->name, &res, 0) == 0) {
-				val = ast_str_buffer(res);
-			} else {
-				val = NULL;
-			}
-		} else {
-			val = pbx_builtin_getvar_helper(chan, var->name);
-		}

[... 1552 lines stripped ...]



More information about the asterisk-commits mailing list