[asterisk-commits] jrose: branch jrose/bridge_projects r384821 - in /team/jrose/bridge_projects:...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Fri Apr 5 14:35:43 CDT 2013
Author: jrose
Date: Fri Apr 5 14:35:37 2013
New Revision: 384821
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=384821
Log:
resolve conflict, enable automerge
Modified:
team/jrose/bridge_projects/ (props changed)
team/jrose/bridge_projects/Makefile
team/jrose/bridge_projects/UPGRADE.txt
team/jrose/bridge_projects/apps/app_meetme.c
team/jrose/bridge_projects/apps/app_voicemail.c
team/jrose/bridge_projects/bridges/bridge_holding.c
team/jrose/bridge_projects/bridges/bridge_simple.c
team/jrose/bridge_projects/bridges/bridge_softmix.c
team/jrose/bridge_projects/channels/chan_dahdi.c
team/jrose/bridge_projects/channels/chan_iax2.c
team/jrose/bridge_projects/channels/chan_mgcp.c
team/jrose/bridge_projects/channels/chan_sip.c
team/jrose/bridge_projects/channels/chan_skinny.c
team/jrose/bridge_projects/channels/chan_unistim.c
team/jrose/bridge_projects/channels/sig_pri.c
team/jrose/bridge_projects/channels/sig_pri.h
team/jrose/bridge_projects/channels/sip/include/sip.h
team/jrose/bridge_projects/channels/sip/security_events.c
team/jrose/bridge_projects/configs/chan_dahdi.conf.sample
team/jrose/bridge_projects/contrib/scripts/install_prereq
team/jrose/bridge_projects/funcs/func_channel.c
team/jrose/bridge_projects/include/asterisk/app.h
team/jrose/bridge_projects/include/asterisk/bridging.h
team/jrose/bridge_projects/include/asterisk/bridging_features.h
team/jrose/bridge_projects/include/asterisk/bridging_technology.h
team/jrose/bridge_projects/include/asterisk/channel.h
team/jrose/bridge_projects/include/asterisk/stasis.h
team/jrose/bridge_projects/include/asterisk/test.h
team/jrose/bridge_projects/include/asterisk/uuid.h
team/jrose/bridge_projects/main/abstract_jb.c
team/jrose/bridge_projects/main/app.c
team/jrose/bridge_projects/main/astobj2.c
team/jrose/bridge_projects/main/bridging.c
team/jrose/bridge_projects/main/cdr.c
team/jrose/bridge_projects/main/channel.c
team/jrose/bridge_projects/main/event.c
team/jrose/bridge_projects/main/format_pref.c
team/jrose/bridge_projects/main/http.c
team/jrose/bridge_projects/main/manager.c
team/jrose/bridge_projects/main/manager_channels.c
team/jrose/bridge_projects/main/pbx.c
team/jrose/bridge_projects/main/sorcery.c
team/jrose/bridge_projects/main/stasis.c
team/jrose/bridge_projects/main/stasis_cache.c
team/jrose/bridge_projects/main/test.c
team/jrose/bridge_projects/main/uuid.c
team/jrose/bridge_projects/pbx/pbx_realtime.c
team/jrose/bridge_projects/res/res_calendar_exchange.c
team/jrose/bridge_projects/res/res_format_attr_h264.c
team/jrose/bridge_projects/res/res_jabber.c
team/jrose/bridge_projects/res/res_rtp_asterisk.c
team/jrose/bridge_projects/res/res_sorcery_config.c
team/jrose/bridge_projects/res/res_xmpp.c
team/jrose/bridge_projects/tests/test_stasis.c
team/jrose/bridge_projects/tests/test_uuid.c
Propchange: team/jrose/bridge_projects/
------------------------------------------------------------------------------
automerge = *
Propchange: team/jrose/bridge_projects/
------------------------------------------------------------------------------
--- bridge_projects-integrated (original)
+++ bridge_projects-integrated Fri Apr 5 14:35:37 2013
@@ -1,1 +1,1 @@
-/team/group/bridge_construction:1-383793
+/team/group/bridge_construction:1-384819
Modified: team/jrose/bridge_projects/Makefile
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/Makefile?view=diff&rev=384821&r1=384820&r2=384821
==============================================================================
--- team/jrose/bridge_projects/Makefile (original)
+++ team/jrose/bridge_projects/Makefile Fri Apr 5 14:35:37 2013
@@ -377,25 +377,26 @@
$(OTHER_SUBDIRS): makeopts
+ at _ASTCFLAGS="$(OTHER_SUBDIR_CFLAGS) $(_ASTCFLAGS)" ASTCFLAGS="$(ASTCFLAGS)" _ASTLDFLAGS="$(_ASTLDFLAGS)" ASTLDFLAGS="$(ASTLDFLAGS)" $(SUBMAKE) --no-builtin-rules -C $@ SUBDIR=$@ all
-defaults.h: makeopts build_tools/make_defaults_h
+defaults.h: makeopts cleantest build_tools/make_defaults_h
@build_tools/make_defaults_h > $@.tmp
@cmp -s $@.tmp $@ || mv $@.tmp $@
@rm -f $@.tmp
-main/version.c: FORCE
+main/version.c: FORCE cleantest
@build_tools/make_version_c > $@.tmp
@cmp -s $@.tmp $@ || mv $@.tmp $@
@rm -f $@.tmp
-include/asterisk/buildopts.h: menuselect.makeopts
+include/asterisk/buildopts.h: menuselect.makeopts cleantest
@build_tools/make_buildopts_h > $@.tmp
@cmp -s $@.tmp $@ || mv $@.tmp $@
@rm -f $@.tmp
-include/asterisk/build.h:
- @build_tools/make_build_h > $@.tmp
- @cmp -s $@.tmp $@ || mv $@.tmp $@
- @rm -f $@.tmp
+# build.h must depend on cleantest, or parallel make may wipe it out after it's
+# been created. But since build.h contains a timestamp, the cmp trick used above
+# won't work. Just testing for existence is good enough.
+include/asterisk/build.h: cleantest
+ @test -f $@ || build_tools/make_build_h > $@
$(SUBDIRS_CLEAN):
+@$(SUBMAKE) -C $(@:-clean=) clean
@@ -449,7 +450,7 @@
done
$(MAKE) -C sounds install
-doc/core-en_US.xml: makeopts $(foreach dir,$(MOD_SUBDIRS),$(shell $(GREP) -l "language=\"en_US\"" $(dir)/*.c $(dir)/*.cc 2>/dev/null))
+doc/core-en_US.xml: makeopts cleantest $(foreach dir,$(MOD_SUBDIRS),$(shell $(GREP) -l "language=\"en_US\"" $(dir)/*.c $(dir)/*.cc 2>/dev/null))
@printf "Building Documentation For: "
@echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" > $@
@echo "<!DOCTYPE docs SYSTEM \"appdocsxml.dtd\">" >> $@
@@ -463,7 +464,7 @@
@echo
@echo "</docs>" >> $@
-doc/full-en_US.xml: makeopts $(foreach dir,$(MOD_SUBDIRS),$(shell $(GREP) -l "language=\"en_US\"" $(dir)/*.c $(dir)/*.cc 2>/dev/null))
+doc/full-en_US.xml: makeopts cleantest $(foreach dir,$(MOD_SUBDIRS),$(shell $(GREP) -l "language=\"en_US\"" $(dir)/*.c $(dir)/*.cc 2>/dev/null))
ifeq ($(PYTHON),:)
@echo "--------------------------------------------------------------------------"
@echo "--- Please install python to build full documentation ---"
Modified: team/jrose/bridge_projects/UPGRADE.txt
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/UPGRADE.txt?view=diff&rev=384821&r1=384820&r2=384821
==============================================================================
--- team/jrose/bridge_projects/UPGRADE.txt (original)
+++ team/jrose/bridge_projects/UPGRADE.txt Fri Apr 5 14:35:37 2013
@@ -67,6 +67,7 @@
- Analog port dialing and deferred DTMF dialing for PRI now distinguishes
between 'w' and 'W'. The 'w' pauses dialing for half a second. The 'W'
pauses dialing for one second.
+ - The default for inband_on_proceeding has changed to no.
Dialplan:
- All channel and global variable names are evaluated in a case-sensitive manner.
@@ -191,7 +192,7 @@
configuration option. Symptoms of this include one way media or no media flow.
chan_unistim
- - Due to massive update in chan_unistim phone keys functions and on-screen
+ - Due to massive update in chan_unistim phone keys functions and on-screen
information changed.
users.conf:
@@ -263,10 +264,10 @@
unchanged.
Module Support Level
- - All modules in the addons, apps, bridge, cdr, cel, channels, codecs,
+ - All modules in the addons, apps, bridge, cdr, cel, channels, codecs,
formats, funcs, pbx, and res have been updated to include MODULEINFO data
that includes <support_level> tags with a value of core, extended, or deprecated.
- More information is available on the Asterisk wiki at
+ More information is available on the Asterisk wiki at
https://wiki.asterisk.org/wiki/display/AST/Asterisk+Module+Support+States
Deprecated modules are now marked to not build by default and must be explicitly
Modified: team/jrose/bridge_projects/apps/app_meetme.c
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/apps/app_meetme.c?view=diff&rev=384821&r1=384820&r2=384821
==============================================================================
--- team/jrose/bridge_projects/apps/app_meetme.c (original)
+++ team/jrose/bridge_projects/apps/app_meetme.c Fri Apr 5 14:35:37 2013
@@ -5926,7 +5926,16 @@
ringing_trunk = sla_choose_ringing_trunk(ringing_station->station, &s_trunk_ref, 1);
ast_mutex_unlock(&sla.lock);
if (!ringing_trunk) {
+ /* This case happens in a bit of a race condition. If two stations answer
+ * the outbound call at the same time, the first one will get connected to
+ * the trunk. When the second one gets here, it will not see any trunks
+ * ringing so we have no idea what to conect it to. So, we just hang up
+ * on it. */
ast_debug(1, "Found no ringing trunk for station '%s' to answer!\n", ringing_station->station->name);
+ ast_dial_join(ringing_station->station->dial);
+ ast_dial_destroy(ringing_station->station->dial);
+ ringing_station->station->dial = NULL;
+ ast_free(ringing_station);
break;
}
/* Track the channel that answered this trunk */
Modified: team/jrose/bridge_projects/apps/app_voicemail.c
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/apps/app_voicemail.c?view=diff&rev=384821&r1=384820&r2=384821
==============================================================================
--- team/jrose/bridge_projects/apps/app_voicemail.c (original)
+++ team/jrose/bridge_projects/apps/app_voicemail.c Fri Apr 5 14:35:37 2013
@@ -5944,7 +5944,10 @@
if (inboxcount2(ext_context, &urgentvoicemails, &newvoicemails, &oldvoicemails)) {
ast_log(AST_LOG_ERROR, "Problem in calculating number of voicemail messages available for extension %s\n", extension);
} else {
- snprintf(arguments, sizeof(arguments), "%s %s %s %d %d %d &", externnotify, context, extension, newvoicemails, oldvoicemails, urgentvoicemails);
+ snprintf(arguments, sizeof(arguments), "%s %s %s %d %d %d &",
+ externnotify, S_OR(context, "\"\""),
+ extension, newvoicemails,
+ oldvoicemails, urgentvoicemails);
ast_debug(1, "Executing %s\n", arguments);
ast_safe_system(arguments);
}
@@ -10950,7 +10953,6 @@
/* If ADSI is supported, setup login screen */
adsi_begin(chan, &useadsi);
- ast_test_suite_assert(valid);
if (!valid) {
goto out;
}
@@ -12627,7 +12629,7 @@
{
struct stasis_subscription_change *change;
/* Only looking for subscription change notices here */
- if (stasis_message_type(msg) != stasis_subscription_change()) {
+ if (stasis_message_type(msg) != stasis_subscription_change_type()) {
return;
}
@@ -12656,7 +12658,7 @@
mwi_sub_sub = stasis_subscribe(stasis_mwi_topic_all(), mwi_event_cb, NULL);
if (mwi_sub_sub) {
- struct ao2_container *cached = stasis_cache_dump(stasis_mwi_topic_cached(), stasis_subscription_change());
+ struct ao2_container *cached = stasis_cache_dump(stasis_mwi_topic_cached(), stasis_subscription_change_type());
if (cached) {
ao2_callback(cached, OBJ_MULTIPLE | OBJ_NODATA, dump_cache, NULL);
}
@@ -14895,8 +14897,8 @@
AST_LIST_LOCK(&users);
AST_LIST_TRAVERSE_SAFE_BEGIN(&users, vmu, list) {
- if (!strncmp(context, vmu->context, sizeof(context))
- && !strncmp(mailbox, vmu->mailbox, sizeof(mailbox))) {
+ if (!strcmp(context, vmu->context)
+ && !strcmp(mailbox, vmu->mailbox)) {
AST_LIST_REMOVE_CURRENT(list);
ast_free(vmu);
break;
Modified: team/jrose/bridge_projects/bridges/bridge_holding.c
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/bridges/bridge_holding.c?view=diff&rev=384821&r1=384820&r2=384821
==============================================================================
--- team/jrose/bridge_projects/bridges/bridge_holding.c (original)
+++ team/jrose/bridge_projects/bridges/bridge_holding.c Fri Apr 5 14:35:37 2013
@@ -255,7 +255,7 @@
static int holding_bridge_write(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_frame *frame)
{
- struct ast_bridge_channel *other;
+ struct ast_bridge_channel *cur;
struct holding_channel *hc = bridge_channel->tech_pvt;
/* If there is no tech_pvt, then the channel failed to allocate one when it joined and is borked. Don't listen to him. */
@@ -269,21 +269,12 @@
}
/* Ok, so we are the announcer and there are one or more people available to receive our writes. Let's do it. */
- AST_LIST_TRAVERSE(&bridge->channels, other, entry) {
- if (!other->tech_pvt) {
+ AST_LIST_TRAVERSE(&bridge->channels, cur, entry) {
+ if (bridge_channel == cur || !cur->tech_pvt) {
continue;
}
- if (bridge_channel == other) {
- continue;
- }
-
- if (other->state == AST_BRIDGE_CHANNEL_STATE_WAIT) {
-/* BUGBUG need to handle control frames in a bridge tech specific way here. Mostly just queue action to bridge channel. */
- if (!other->suspended
- || ast_is_deferrable_frame(frame)) {
- ast_bridge_channel_queue_frame(other, frame);
- }
- }
+
+ ast_bridge_channel_queue_frame(cur, frame);
}
return 0;
Modified: team/jrose/bridge_projects/bridges/bridge_simple.c
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/bridges/bridge_simple.c?view=diff&rev=384821&r1=384820&r2=384821
==============================================================================
--- team/jrose/bridge_projects/bridges/bridge_simple.c (original)
+++ team/jrose/bridge_projects/bridges/bridge_simple.c Fri Apr 5 14:35:37 2013
@@ -82,13 +82,7 @@
}
/* The bridging core takes care of freeing the passed in frame. */
- if (other->state == AST_BRIDGE_CHANNEL_STATE_WAIT) {
-/* BUGBUG need to handle control frames in a bridge tech specific way here. Mostly just queue action to bridge channel. */
- if (!other->suspended
- || ast_is_deferrable_frame(frame)) {
- ast_bridge_channel_queue_frame(other, frame);
- }
- }
+ ast_bridge_channel_queue_frame(other, frame);
return 0;
}
Modified: team/jrose/bridge_projects/bridges/bridge_softmix.c
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/bridges/bridge_softmix.c?view=diff&rev=384821&r1=384820&r2=384821
==============================================================================
--- team/jrose/bridge_projects/bridges/bridge_softmix.c (original)
+++ team/jrose/bridge_projects/bridges/bridge_softmix.c Fri Apr 5 14:35:37 2013
@@ -366,19 +366,47 @@
/*! \brief Function called when a channel is unsuspended from the bridge */
static void softmix_bridge_unsuspend(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
{
- softmix_poke_thread(bridge->tech_pvt);
+ if (bridge->tech_pvt) {
+ softmix_poke_thread(bridge->tech_pvt);
+ }
+}
+
+/*!
+ * \internal
+ * \brief Indicate a source change to the channel.
+ * \since 12.0.0
+ *
+ * \param bridge_channel Which channel source is changing.
+ *
+ * \return Nothing
+ */
+static void softmix_src_change(struct ast_bridge_channel *bridge_channel)
+{
+ struct ast_frame frame = {
+ .frametype = AST_FRAME_CONTROL,
+ .subclass.integer = AST_CONTROL_SRCCHANGE
+ };
+
+ ast_bridge_channel_queue_frame(bridge_channel, &frame);
}
/*! \brief Function called when a channel is joined into the bridge */
static int softmix_bridge_join(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
{
struct softmix_channel *sc;
- struct softmix_bridge_data *softmix_data = bridge->tech_pvt;
+ struct softmix_bridge_data *softmix_data;
+
+ softmix_data = bridge->tech_pvt;
+ if (!softmix_data) {
+ return -1;
+ }
/* Create a new softmix_channel structure and allocate various things on it */
if (!(sc = ast_calloc(1, sizeof(*sc)))) {
return -1;
}
+
+ softmix_src_change(bridge_channel);
/* Can't forget the lock */
ast_mutex_init(&sc->lock);
@@ -406,6 +434,8 @@
}
bridge_channel->tech_pvt = NULL;
+ softmix_src_change(bridge_channel);
+
/* Drop mutex lock */
ast_mutex_destroy(&sc->lock);
@@ -421,9 +451,28 @@
/*!
* \internal
- * \brief If the bridging core passes DTMF to us, then they want it to be distributed out to all memebers. Do that here.
- */
-static void softmix_pass_dtmf(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_frame *frame)
+ * \brief Pass the given frame to everyone else.
+ * \since 12.0.0
+ *
+ * \param bridge What bridge to distribute frame.
+ * \param bridge_channel Channel to optionally not pass frame to. (NULL to pass to everyone)
+ * \param frame Frame to pass.
+ *
+ * \return Nothing
+ */
+static void softmix_pass_everyone_else(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_frame *frame)
+{
+ struct ast_bridge_channel *cur;
+
+ AST_LIST_TRAVERSE(&bridge->channels, cur, entry) {
+ if (cur == bridge_channel) {
+ continue;
+ }
+ ast_bridge_channel_queue_frame(cur, frame);
+ }
+}
+
+static void softmix_pass_video_top_priority(struct ast_bridge *bridge, struct ast_frame *frame)
{
struct ast_bridge_channel *cur;
@@ -431,21 +480,6 @@
if (cur->suspended) {
continue;
}
- if (cur == bridge_channel) {
- continue;
- }
- ast_bridge_channel_queue_frame(cur, frame);
- }
-}
-
-static void softmix_pass_video_top_priority(struct ast_bridge *bridge, struct ast_frame *frame)
-{
- struct ast_bridge_channel *cur;
-
- AST_LIST_TRAVERSE(&bridge->channels, cur, entry) {
- if (cur->suspended) {
- continue;
- }
if (ast_bridge_is_video_src(bridge, cur->chan) == 1) {
ast_bridge_channel_queue_frame(cur, frame);
break;
@@ -453,23 +487,65 @@
}
}
-static void softmix_pass_video_all(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_frame *frame, int echo)
-{
- struct ast_bridge_channel *cur;
-
- AST_LIST_TRAVERSE(&bridge->channels, cur, entry) {
- if (cur->suspended) {
- continue;
- }
- if (cur == bridge_channel && !echo) {
- continue;
- }
- ast_bridge_channel_queue_frame(cur, frame);
- }
-}
-
-/*! \brief Function called when a channel writes a frame into the bridge */
-static int softmix_bridge_write(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_frame *frame)
+/*!
+ * \internal
+ * \brief Determine what to do with a video frame.
+ * \since 12.0.0
+ *
+ * \param bridge Which bridge is getting the frame
+ * \param bridge_channel Which channel is writing the frame.
+ * \param frame What is being written.
+ *
+ * \return Nothing
+ */
+static void softmix_bridge_write_video(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_frame *frame)
+{
+ struct softmix_channel *sc;
+ int video_src_priority;
+
+ /* Determine if the video frame should be distributed or not */
+ switch (bridge->video_mode.mode) {
+ case AST_BRIDGE_VIDEO_MODE_NONE:
+ break;
+ case AST_BRIDGE_VIDEO_MODE_SINGLE_SRC:
+ video_src_priority = ast_bridge_is_video_src(bridge, bridge_channel->chan);
+ if (video_src_priority == 1) {
+ /* Pass to me and everyone else. */
+ softmix_pass_everyone_else(bridge, NULL, frame);
+ }
+ break;
+ case AST_BRIDGE_VIDEO_MODE_TALKER_SRC:
+ sc = bridge_channel->tech_pvt;
+ ast_mutex_lock(&sc->lock);
+ ast_bridge_update_talker_src_video_mode(bridge, bridge_channel->chan,
+ sc->video_talker.energy_average,
+ ast_format_get_video_mark(&frame->subclass.format));
+ ast_mutex_unlock(&sc->lock);
+ video_src_priority = ast_bridge_is_video_src(bridge, bridge_channel->chan);
+ if (video_src_priority == 1) {
+ int num_src = ast_bridge_number_video_src(bridge);
+ int echo = num_src > 1 ? 0 : 1;
+
+ softmix_pass_everyone_else(bridge, echo ? NULL : bridge_channel, frame);
+ } else if (video_src_priority == 2) {
+ softmix_pass_video_top_priority(bridge, frame);
+ }
+ break;
+ }
+}
+
+/*!
+ * \internal
+ * \brief Determine what to do with a voice frame.
+ * \since 12.0.0
+ *
+ * \param bridge Which bridge is getting the frame
+ * \param bridge_channel Which channel is writing the frame.
+ * \param frame What is being written.
+ *
+ * \return Nothing
+ */
+static void softmix_bridge_write_voice(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_frame *frame)
{
struct softmix_channel *sc = bridge_channel->tech_pvt;
struct softmix_bridge_data *softmix_data = bridge->tech_pvt;
@@ -479,49 +555,8 @@
bridge_channel->tech_args.silence_threshold :
DEFAULT_SOFTMIX_SILENCE_THRESHOLD;
char update_talking = -1; /* if this is set to 0 or 1, tell the bridge that the channel has started or stopped talking. */
- int res = 0;
-
- /* Only accept audio frames, all others are unsupported */
- if (frame->frametype == AST_FRAME_DTMF_END || frame->frametype == AST_FRAME_DTMF_BEGIN) {
- softmix_pass_dtmf(bridge, bridge_channel, frame);
- return res;
- } else if (frame->frametype != AST_FRAME_VOICE && frame->frametype != AST_FRAME_VIDEO) {
- /* Frame type unsupported. */
- res = -1;
- return res;
- } else if (frame->datalen == 0) {
- return res;
- }
-
- /* Determine if this video frame should be distributed or not */
- if (frame->frametype == AST_FRAME_VIDEO) {
- int num_src = ast_bridge_number_video_src(bridge);
- int video_src_priority = ast_bridge_is_video_src(bridge, bridge_channel->chan);
-
- switch (bridge->video_mode.mode) {
- case AST_BRIDGE_VIDEO_MODE_NONE:
- break;
- case AST_BRIDGE_VIDEO_MODE_SINGLE_SRC:
- if (video_src_priority == 1) {
- softmix_pass_video_all(bridge, bridge_channel, frame, 1);
- }
- break;
- case AST_BRIDGE_VIDEO_MODE_TALKER_SRC:
- ast_mutex_lock(&sc->lock);
- ast_bridge_update_talker_src_video_mode(bridge, bridge_channel->chan, sc->video_talker.energy_average, ast_format_get_video_mark(&frame->subclass.format));
- ast_mutex_unlock(&sc->lock);
- if (video_src_priority == 1) {
- int echo = num_src > 1 ? 0 : 1;
- softmix_pass_video_all(bridge, bridge_channel, frame, echo);
- } else if (video_src_priority == 2) {
- softmix_pass_video_top_priority(bridge, frame);
- }
- break;
- }
- return res;
- }
-
- /* If we made it here, we are going to write the frame into the conference */
+
+ /* Write the frame into the conference */
ast_mutex_lock(&sc->lock);
ast_dsp_silence_with_energy(sc->dsp, frame, &totalsilence, &cur_energy);
@@ -569,6 +604,69 @@
if (update_talking != -1) {
ast_bridge_notify_talking(bridge_channel, update_talking);
+ }
+}
+
+/*!
+ * \internal
+ * \brief Determine what to do with a control frame.
+ * \since 12.0.0
+ *
+ * \param bridge Which bridge is getting the frame
+ * \param bridge_channel Which channel is writing the frame.
+ * \param frame What is being written.
+ *
+ * \return Nothing
+ */
+static void softmix_bridge_write_control(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_frame *frame)
+{
+/* BUGBUG need to look at channel roles to determine what to do with control frame. */
+ /*! \todo BUGBUG softmix_bridge_write_control() not written */
+}
+
+/*!
+ * \internal
+ * \brief Determine what to do with a frame written into the bridge.
+ * \since 12.0.0
+ *
+ * \param bridge Which bridge is getting the frame
+ * \param bridge_channel Which channel is writing the frame.
+ * \param frame What is being written.
+ *
+ * \retval 0 on success
+ * \retval -1 on failure
+ *
+ * \note On entry, bridge is already locked.
+ */
+static int softmix_bridge_write(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_frame *frame)
+{
+ int res = 0;
+
+ if (!bridge->tech_pvt || !bridge_channel->tech_pvt) {
+ return -1;
+ }
+
+ switch (frame->frametype) {
+ case AST_FRAME_DTMF_BEGIN:
+ case AST_FRAME_DTMF_END:
+ softmix_pass_everyone_else(bridge, bridge_channel, frame);
+ break;
+ case AST_FRAME_VOICE:
+ softmix_bridge_write_voice(bridge, bridge_channel, frame);
+ break;
+ case AST_FRAME_VIDEO:
+ softmix_bridge_write_video(bridge, bridge_channel, frame);
+ break;
+ case AST_FRAME_CONTROL:
+ softmix_bridge_write_control(bridge, bridge_channel, frame);
+ break;
+ case AST_FRAME_BRIDGE_ACTION:
+ softmix_pass_everyone_else(bridge, bridge_channel, frame);
+ break;
+ default:
+ ast_debug(3, "Frame type %d unsupported\n", frame->frametype);
+ res = -1;
+ break;
}
return res;
@@ -892,7 +990,7 @@
ast_callid_threadassoc_add(bridge->callid);
}
- ast_debug(1, "Starting mixing thread for bridge %p\n", bridge);
+ ast_debug(1, "Bridge %s: starting mixing thread\n", bridge->uniqueid);
softmix_data = bridge->tech_pvt;
while (!softmix_data->stop) {
@@ -921,7 +1019,7 @@
ast_bridge_unlock(bridge);
- ast_debug(1, "Stopping mixing thread for bridge %p\n", bridge);
+ ast_debug(1, "Bridge %s: stopping mixing thread\n", bridge->uniqueid);
return NULL;
}
Modified: team/jrose/bridge_projects/channels/chan_dahdi.c
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/channels/chan_dahdi.c?view=diff&rev=384821&r1=384820&r2=384821
==============================================================================
--- team/jrose/bridge_projects/channels/chan_dahdi.c (original)
+++ team/jrose/bridge_projects/channels/chan_dahdi.c Fri Apr 5 14:35:37 2013
@@ -5414,7 +5414,7 @@
}
ast_str_set(&uniqueid, 0, "%s@%s", mailbox, context);
- mwi_message = stasis_cache_get(stasis_mwi_topic_cached(), stasis_mwi_state_message(), ast_str_buffer(uniqueid));
+ mwi_message = stasis_cache_get(stasis_mwi_topic_cached(), stasis_mwi_state_type(), ast_str_buffer(uniqueid));
if (mwi_message) {
struct stasis_mwi_state *mwi_state = stasis_message_data(mwi_message);
@@ -12951,6 +12951,7 @@
pris[span].pri.layer1_ignored = 0;
}
pris[span].pri.append_msn_to_user_tag = conf->pri.pri.append_msn_to_user_tag;
+ pris[span].pri.inband_on_proceeding = conf->pri.pri.inband_on_proceeding;
ast_copy_string(pris[span].pri.initial_user_tag, conf->chan.cid_tag, sizeof(pris[span].pri.initial_user_tag));
ast_copy_string(pris[span].pri.msn_list, conf->pri.pri.msn_list, sizeof(pris[span].pri.msn_list));
#if defined(HAVE_PRI_MWI)
@@ -18218,6 +18219,8 @@
#endif /* defined(HAVE_PRI_MWI) */
} else if (!strcasecmp(v->name, "append_msn_to_cid_tag")) {
confp->pri.pri.append_msn_to_user_tag = ast_true(v->value);
+ } else if (!strcasecmp(v->name, "inband_on_proceeding")) {
+ confp->pri.pri.inband_on_proceeding = ast_true(v->value);
#if defined(HAVE_PRI_DISPLAY_TEXT)
} else if (!strcasecmp(v->name, "display_send")) {
confp->pri.pri.display_flags_send = dahdi_display_text_option(v->value);
Modified: team/jrose/bridge_projects/channels/chan_iax2.c
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/channels/chan_iax2.c?view=diff&rev=384821&r1=384820&r2=384821
==============================================================================
--- team/jrose/bridge_projects/channels/chan_iax2.c (original)
+++ team/jrose/bridge_projects/channels/chan_iax2.c Fri Apr 5 14:35:37 2013
@@ -8755,7 +8755,7 @@
}
ast_str_set(&uniqueid, 0, "%s@%s", mailbox, context);
- msg = stasis_cache_get(stasis_mwi_topic_cached(), stasis_mwi_state_message(), ast_str_buffer(uniqueid));
+ msg = stasis_cache_get(stasis_mwi_topic_cached(), stasis_mwi_state_type(), ast_str_buffer(uniqueid));
if (msg) {
struct stasis_mwi_state *mwi_state = stasis_message_data(msg);
Modified: team/jrose/bridge_projects/channels/chan_mgcp.c
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/channels/chan_mgcp.c?view=diff&rev=384821&r1=384820&r2=384821
==============================================================================
--- team/jrose/bridge_projects/channels/chan_mgcp.c (original)
+++ team/jrose/bridge_projects/channels/chan_mgcp.c Fri Apr 5 14:35:37 2013
@@ -507,7 +507,7 @@
ast_str_set(&uniqueid, 0, "%s@%s", mbox, cntx);
- msg = stasis_cache_get(stasis_mwi_topic_cached(), stasis_mwi_state_message(), ast_str_buffer(uniqueid));
+ msg = stasis_cache_get(stasis_mwi_topic_cached(), stasis_mwi_state_type(), ast_str_buffer(uniqueid));
if (msg) {
struct stasis_mwi_state *mwi_state = stasis_message_data(msg);
Modified: team/jrose/bridge_projects/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/channels/chan_sip.c?view=diff&rev=384821&r1=384820&r2=384821
==============================================================================
--- team/jrose/bridge_projects/channels/chan_sip.c (original)
+++ team/jrose/bridge_projects/channels/chan_sip.c Fri Apr 5 14:35:37 2013
@@ -1009,6 +1009,11 @@
static struct ao2_container *peers;
static struct ao2_container *peers_by_ip;
+/*! \brief A bogus peer, to be used when authentication should fail */
+static struct sip_peer *bogus_peer;
+/*! \brief We can recognise the bogus peer by this invalid MD5 hash */
+#define BOGUS_PEER_MD5SECRET "intentionally_invalid_md5_string"
+
/*! \brief The register list: Other SIP proxies we register with and receive calls from */
static struct ast_register_list {
ASTOBJ_CONTAINER_COMPONENTS(struct sip_registry);
@@ -1157,7 +1162,7 @@
static int transmit_response_with_auth(struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *rand, enum xmittype reliable, const char *header, int stale);
static int transmit_provisional_response(struct sip_pvt *p, const char *msg, const struct sip_request *req, int with_sdp);
static int transmit_response_with_allow(struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable);
-static void transmit_fake_auth_response(struct sip_pvt *p, int sipmethod, struct sip_request *req, enum xmittype reliable);
+static void transmit_fake_auth_response(struct sip_pvt *p, struct sip_request *req, enum xmittype reliable);
static int transmit_request(struct sip_pvt *p, int sipmethod, uint32_t seqno, enum xmittype reliable, int newbranch);
static int transmit_request_with_auth(struct sip_pvt *p, int sipmethod, uint32_t seqno, enum xmittype reliable, int newbranch);
static int transmit_publish(struct sip_epa_entry *epa_entry, enum sip_publish_type publish_type, const char * const explicit_uri);
@@ -16131,7 +16136,9 @@
ast_verb(3, "Registered SIP '%s' at %s\n", peer->name,
ast_sockaddr_stringify(&peer->addr));
}
+ sip_pvt_unlock(pvt);
sip_poke_peer(peer, 0);
+ sip_pvt_lock(pvt);
register_peer_exten(peer, 1);
/* Save User agent */
@@ -16477,6 +16484,7 @@
char a1_hash[256];
char resp_hash[256]="";
char *c;
+ int is_bogus_peer = 0;
int wrongnonce = FALSE;
int good_response;
const char *usednonce = p->nonce;
@@ -16548,8 +16556,14 @@
sip_digest_parser(c, keys);
+ /* We cannot rely on the bogus_peer having a bad md5 value. Someone could
+ * use it to construct valid auth. */
+ if (md5secret && strcmp(md5secret, BOGUS_PEER_MD5SECRET) == 0) {
+ is_bogus_peer = 1;
+ }
+
/* Verify that digest username matches the username we auth as */
- if (strcmp(username, keys[K_USER].s)) {
+ if (strcmp(username, keys[K_USER].s) && !is_bogus_peer) {
ast_log(LOG_WARNING, "username mismatch, have <%s>, digest has <%s>\n",
username, keys[K_USER].s);
/* Oops, we're trying something here */
@@ -16588,7 +16602,8 @@
}
good_response = keys[K_RESP].s &&
- !strncasecmp(keys[K_RESP].s, resp_hash, strlen(resp_hash));
+ !strncasecmp(keys[K_RESP].s, resp_hash, strlen(resp_hash)) &&
+ !is_bogus_peer; /* lastly, check that the peer isn't the fake peer */
if (wrongnonce) {
if (good_response) {
if (sipdebug)
@@ -16653,7 +16668,7 @@
ao2_cleanup(peer);
return;
}
- if (stasis_mwi_state_message() == stasis_message_type(msg)) {
+ if (stasis_mwi_state_type() == stasis_message_type(msg)) {
sip_send_mwi_to_peer(peer, 0);
}
}
@@ -16819,13 +16834,13 @@
/*! \brief Send a fake 401 Unauthorized response when the administrator
wants to hide the names of local devices from fishers
*/
-static void transmit_fake_auth_response(struct sip_pvt *p, int sipmethod, struct sip_request *req, enum xmittype reliable)
+static void transmit_fake_auth_response(struct sip_pvt *p, struct sip_request *req, enum xmittype reliable)
{
/* We have to emulate EXACTLY what we'd get with a good peer
* and a bad password, or else we leak information. */
- const char *response = "407 Proxy Authentication Required";
- const char *reqheader = "Proxy-Authorization";
- const char *respheader = "Proxy-Authenticate";
+ const char *response = "401 Unauthorized";
+ const char *reqheader = "Authorization";
+ const char *respheader = "WWW-Authenticate";
const char *authtoken;
struct ast_str *buf;
char *c;
@@ -16840,36 +16855,31 @@
[K_LAST] = { NULL, NULL}
};
- if (sipmethod == SIP_REGISTER || sipmethod == SIP_SUBSCRIBE) {
- response = "401 Unauthorized";
- reqheader = "Authorization";
- respheader = "WWW-Authenticate";
- }
authtoken = sip_get_header(req, reqheader);
if (req->ignore && !ast_strlen_zero(p->nonce) && ast_strlen_zero(authtoken)) {
/* This is a retransmitted invite/register/etc, don't reconstruct authentication
* information */
- transmit_response_with_auth(p, response, req, p->nonce, 0, respheader, 0);
+ transmit_response_with_auth(p, response, req, p->nonce, reliable, respheader, 0);
/* Schedule auto destroy in 32 seconds (according to RFC 3261) */
sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
return;
} else if (ast_strlen_zero(p->nonce) || ast_strlen_zero(authtoken)) {
/* We have no auth, so issue challenge and request authentication */
build_nonce(p, 1);
- transmit_response_with_auth(p, response, req, p->nonce, 0, respheader, 0);
+ transmit_response_with_auth(p, response, req, p->nonce, reliable, respheader, 0);
/* Schedule auto destroy in 32 seconds */
sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
return;
}
if (!(buf = ast_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN))) {
- transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq);
+ __transmit_response(p, "403 Forbidden", &p->initreq, reliable);
return;
}
/* Make a copy of the response and parse it */
if (ast_str_set(&buf, 0, "%s", authtoken) == AST_DYNSTR_BUILD_FAILED) {
- transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq);
+ __transmit_response(p, "403 Forbidden", &p->initreq, reliable);
return;
}
@@ -16907,7 +16917,7 @@
/* Schedule auto destroy in 32 seconds */
sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
} else {
- transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq);
+ __transmit_response(p, "403 Forbidden", &p->initreq, reliable);
}
}
@@ -17017,7 +17027,7 @@
if (!AST_LIST_EMPTY(&domain_list)) {
if (!check_sip_domain(domain, NULL, 0)) {
if (sip_cfg.alwaysauthreject) {
- transmit_fake_auth_response(p, SIP_REGISTER, &p->initreq, XMIT_UNRELIABLE);
+ transmit_fake_auth_response(p, &p->initreq, XMIT_UNRELIABLE);
} else {
transmit_response(p, "404 Not found (unknown domain)", &p->initreq);
}
@@ -17043,6 +17053,13 @@
}
}
peer = sip_find_peer(name, NULL, TRUE, FINDPEERS, FALSE, 0);
+
+ /* If we don't want username disclosure, use the bogus_peer when a user
+ * is not found. */
+ if (!peer && sip_cfg.alwaysauthreject && sip_cfg.autocreatepeer == AUTOPEERS_DISABLED) {
+ peer = bogus_peer;
+ sip_ref_peer(peer, "register_verify: ref the bogus_peer");
+ }
if (!(peer && ast_apply_acl(peer->acl, addr, "SIP Peer ACL: "))) {
/* Peer fails ACL check */
@@ -17135,7 +17152,7 @@
switch (parse_register_contact(p, peer, req)) {
case PARSE_REGISTER_DENIED:
ast_log(LOG_WARNING, "Registration denied because of contact ACL\n");
- transmit_response_with_date(p, "403 Forbidden (ACL)", req);
+ transmit_response_with_date(p, "403 Forbidden", req);
res = 0;
break;
case PARSE_REGISTER_FAILED:
@@ -17163,9 +17180,9 @@
}
if (!res) {
if (send_mwi) {
- ao2_unlock(p);
+ sip_pvt_unlock(p);
sip_send_mwi_to_peer(peer, 0);
- ao2_lock(p);
+ sip_pvt_lock(p);
} else {
update_peer_lastmsgssent(peer, -1, 0);
}
@@ -17175,7 +17192,7 @@
switch (res) {
case AUTH_SECRET_FAILED:
/* Wrong password in authentication. Go away, don't try again until you fixed it */
- transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq);
+ transmit_response(p, "403 Forbidden", &p->initreq);
if (global_authfailureevents) {
const char *peer_addr = ast_strdupa(ast_sockaddr_stringify_addr(addr));
const char *peer_port = ast_strdupa(ast_sockaddr_stringify_port(addr));
@@ -17198,7 +17215,7 @@
case AUTH_PEER_NOT_DYNAMIC:
case AUTH_ACL_FAILED:
if (sip_cfg.alwaysauthreject) {
- transmit_fake_auth_response(p, SIP_REGISTER, &p->initreq, XMIT_UNRELIABLE);
+ transmit_fake_auth_response(p, &p->initreq, XMIT_UNRELIABLE);
if (global_authfailureevents) {
const char *peer_addr = ast_strdupa(ast_sockaddr_stringify_addr(addr));
const char *peer_port = ast_strdupa(ast_sockaddr_stringify_port(addr));
@@ -18237,7 +18254,19 @@
ast_verbose("No matching peer for '%s' from '%s'\n",
of, ast_sockaddr_stringify(&p->recv));
}
- return AUTH_DONT_KNOW;
+
+ /* If you don't mind, we can return 404s for devices that do
+ * not exist: username disclosure. If we allow guests, there
+ * is no way around that. */
+ if (sip_cfg.allowguest || !sip_cfg.alwaysauthreject) {
+ return AUTH_DONT_KNOW;
+ }
+
+ /* If you do mind, we use a peer that will never authenticate.
+ * This ensures that we follow the same code path as regular
+ * auth: less chance for username disclosure. */
+ peer = bogus_peer;
+ sip_ref_peer(peer, "sip_ref_peer: check_peer_ok: must ref bogus_peer so unreffing it does not fail");
}
/* build_peer, called through sip_find_peer, is not able to check the
@@ -18260,9 +18289,10 @@
sip_unref_peer(peer, "sip_unref_peer: check_peer_ok: from sip_find_peer call, early return of AUTH_ACL_FAILED");
return AUTH_ACL_FAILED;
}
- if (debug)
+ if (debug && peer != bogus_peer) {
ast_verbose("Found peer '%s' for '%s' from %s\n",
peer->name, of, ast_sockaddr_stringify(&p->recv));
+ }
/* XXX what about p->prefs = peer->prefs; ? */
/* Set Frame packetization */
@@ -18545,8 +18575,6 @@
} else {
res = AUTH_RTP_FAILED;
}
- } else if (sip_cfg.alwaysauthreject) {
- res = AUTH_FAKE_AUTH; /* reject with fake authorization request */
} else {
res = AUTH_SECRET_FAILED; /* we don't want any guests, authentication will fail */
}
@@ -18681,13 +18709,8 @@
return;
}
if (res < 0) { /* Something failed in authentication */
- if (res == AUTH_FAKE_AUTH) {
- ast_log(LOG_NOTICE, "Sending fake auth rejection for device %s\n", sip_get_header(req, "From"));
- transmit_fake_auth_response(p, SIP_MESSAGE, req, XMIT_UNRELIABLE);
- } else {
- ast_log(LOG_NOTICE, "Failed to authenticate device %s\n", sip_get_header(req, "From"));
- transmit_response(p, "403 Forbidden", req);
- }
+ ast_log(LOG_NOTICE, "Failed to authenticate device %s\n", sip_get_header(req, "From"));
+ transmit_response(p, "403 Forbidden", req);
sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
return;
}
@@ -24845,13 +24868,8 @@
return 0;
}
if (res < 0) { /* Something failed in authentication */
- if (res == AUTH_FAKE_AUTH) {
- ast_log(LOG_NOTICE, "Sending fake auth rejection for device %s\n", sip_get_header(req, "From"));
- transmit_fake_auth_response(p, SIP_OPTIONS, req, XMIT_UNRELIABLE);
- } else {
- ast_log(LOG_NOTICE, "Failed to authenticate device %s\n", sip_get_header(req, "From"));
- transmit_response(p, "403 Forbidden", req);
- }
+ ast_log(LOG_NOTICE, "Failed to authenticate device %s\n", sip_get_header(req, "From"));
+ transmit_response(p, "403 Forbidden", req);
sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
return 0;
}
@@ -25496,13 +25514,8 @@
goto request_invite_cleanup;
}
if (res < 0) { /* Something failed in authentication */
- if (res == AUTH_FAKE_AUTH) {
- ast_log(LOG_NOTICE, "Sending fake auth rejection for device %s\n", sip_get_header(req, "From"));
[... 3952 lines stripped ...]
More information about the asterisk-commits
mailing list