diff --git a/apps/app_dial.c b/apps/app_dial.c index 5698c1945cb8e8e3ab168f5af13850e0363a2b18..b52a97b2de257c6661dfbddde4dbba0c0e75da00 100644 --- a/apps/app_dial.c +++ b/apps/app_dial.c @@ -717,6 +717,10 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in, ast_verb(3, "%s requested a video update, passing it to %s\n", c->name, in->name); ast_indicate(in, AST_CONTROL_VIDUPDATE); break; + case AST_CONTROL_SRCUPDATE: + ast_verb(3, "%s requested a source update, passing it to %s\n", c->name, in->name); + ast_indicate(in, AST_CONTROL_SRCUPDATE); + break; case AST_CONTROL_PROCEEDING: ast_verb(3, "%s is proceeding passing it to %s\n", c->name, in->name); if (single && CAN_EARLY_BRIDGE(peerflags)) @@ -820,7 +824,8 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in, if (single && (f->frametype == AST_FRAME_CONTROL) && ((f->subclass == AST_CONTROL_HOLD) || (f->subclass == AST_CONTROL_UNHOLD) || - (f->subclass == AST_CONTROL_VIDUPDATE))) { + (f->subclass == AST_CONTROL_VIDUPDATE) || + (f->subclass == AST_CONTROL_SRCUPDATE))) { ast_verb(3, "%s requested special control %d, passing it to %s\n", in->name, f->subclass, outgoing->chan->name); ast_indicate_data(outgoing->chan, f->subclass, f->data, f->datalen); } diff --git a/apps/app_followme.c b/apps/app_followme.c index 9dd130b9da3e0039a37224aadbc29c2cb4258769..4e83c819f1928c5c8defd3fbf6a40c2d0a23c8c5 100644 --- a/apps/app_followme.c +++ b/apps/app_followme.c @@ -656,6 +656,9 @@ static struct ast_channel *wait_for_winner(struct findme_user_listptr *findme_us case AST_CONTROL_VIDUPDATE: ast_verb(3, "%s requested a video update, passing it to %s\n", winner->name, caller->name); break; + case AST_CONTROL_SRCUPDATE: + ast_verb(3, "%s requested a source update, passing it to %s\n", winner->name, caller->name); + break; case AST_CONTROL_PROCEEDING: ast_verb(3, "%s is proceeding passing it to %s\n", winner->name,caller->name); break; diff --git a/channels/chan_alsa.c b/channels/chan_alsa.c index ec1107695ed50b9f78e4f650be05e1c388ffe95b..3e9199fce437c9fea39d732cc10a929a32310bde 100644 --- a/channels/chan_alsa.c +++ b/channels/chan_alsa.c @@ -510,6 +510,7 @@ static int alsa_indicate(struct ast_channel *chan, int cond, const void *data, s case AST_CONTROL_PROGRESS: case AST_CONTROL_PROCEEDING: case AST_CONTROL_VIDUPDATE: + case AST_CONTROL_SRCUPDATE: break; case AST_CONTROL_HOLD: ast_verbose(" << Console Has Been Placed on Hold >> \n"); diff --git a/channels/chan_console.c b/channels/chan_console.c index c558f5b1db992ca0303ea32fa76da7ae436d6df1..7d62e6235c0e6aa8176193f23a903df11c7593d8 100644 --- a/channels/chan_console.c +++ b/channels/chan_console.c @@ -610,6 +610,7 @@ static int console_indicate(struct ast_channel *chan, int cond, const void *data case AST_CONTROL_PROGRESS: case AST_CONTROL_PROCEEDING: case AST_CONTROL_VIDUPDATE: + case AST_CONTROL_SRCUPDATE: break; case AST_CONTROL_HOLD: ast_verb(1, V_BEGIN "Console Has Been Placed on Hold" V_END); diff --git a/channels/chan_h323.c b/channels/chan_h323.c index e61fa101ad81806f65b38d7530f6323bf88e1283..2b1ef51e7cbb742cf533a4ac7a76a499c2bc6ba4 100644 --- a/channels/chan_h323.c +++ b/channels/chan_h323.c @@ -914,6 +914,10 @@ static int oh323_indicate(struct ast_channel *c, int condition, const void *data ast_moh_stop(c); res = 0; break; + case AST_CONTROL_SRCUPDATE: + ast_rtp_new_source(pvt->rtp); + res = 0; + break; case AST_CONTROL_PROCEEDING: case -1: break; diff --git a/channels/chan_mgcp.c b/channels/chan_mgcp.c index f4ce2ce6a2e161021136b73bd7e535cb123138ec..9f334298e9cd77e1529b23956b0ee26741f32f3c 100644 --- a/channels/chan_mgcp.c +++ b/channels/chan_mgcp.c @@ -1479,6 +1479,9 @@ static int mgcp_indicate(struct ast_channel *ast, int ind, const void *data, siz case AST_CONTROL_UNHOLD: ast_moh_stop(ast); break; + case AST_CONTROL_SRCUPDATE: + ast_rtp_new_source(sub->rtp); + break; case -1: transmit_notify_request(sub, ""); break; diff --git a/channels/chan_oss.c b/channels/chan_oss.c index 4f40085fadcf45c1143e275b26ae3295d81e8d66..6269512086f97fe7ce46bf4f5dfcb347d11ac8dd 100644 --- a/channels/chan_oss.c +++ b/channels/chan_oss.c @@ -764,6 +764,7 @@ static int oss_indicate(struct ast_channel *c, int cond, const void *data, size_ case AST_CONTROL_PROGRESS: case AST_CONTROL_PROCEEDING: case AST_CONTROL_VIDUPDATE: + case AST_CONTROL_SRCUPDATE: break; case AST_CONTROL_HOLD: ast_verbose(" << Console Has Been Placed on Hold >> \n"); diff --git a/channels/chan_phone.c b/channels/chan_phone.c index 233e5e829453a27fa65fdf990a6cb84c48ab9f75..48b26c160db3242ad4a3587abdca148871900a60 100644 --- a/channels/chan_phone.c +++ b/channels/chan_phone.c @@ -206,21 +206,24 @@ static int phone_indicate(struct ast_channel *chan, int condition, const void *d int res=-1; ast_debug(1, "Requested indication %d on channel %s\n", condition, chan->name); switch(condition) { - case AST_CONTROL_FLASH: - ioctl(p->fd, IXJCTL_PSTN_SET_STATE, PSTN_ON_HOOK); - usleep(320000); - ioctl(p->fd, IXJCTL_PSTN_SET_STATE, PSTN_OFF_HOOK); + case AST_CONTROL_FLASH: + ioctl(p->fd, IXJCTL_PSTN_SET_STATE, PSTN_ON_HOOK); + usleep(320000); + ioctl(p->fd, IXJCTL_PSTN_SET_STATE, PSTN_OFF_HOOK); p->lastformat = -1; res = 0; break; - case AST_CONTROL_HOLD: - ast_moh_start(chan, data, NULL); - break; - case AST_CONTROL_UNHOLD: - ast_moh_stop(chan); - break; - default: - ast_log(LOG_WARNING, "Condition %d is not supported on channel %s\n", condition, chan->name); + case AST_CONTROL_HOLD: + ast_moh_start(chan, data, NULL); + break; + case AST_CONTROL_UNHOLD: + ast_moh_stop(chan); + break; + case AST_CONTROL_SRCUPDATE: + res = 0; + break; + default: + ast_log(LOG_WARNING, "Condition %d is not supported on channel %s\n", condition, chan->name); } return res; } diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 4343583b2df123c2f4a7c642aea06b8030fc4091..fa9052dfa60e021f9c6c061588f46489e9a602c2 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -5140,6 +5140,9 @@ static int sip_indicate(struct ast_channel *ast, int condition, const void *data } } break; + case AST_CONTROL_SRCUPDATE: + ast_rtp_new_source(p->rtp); + break; case -1: res = -1; break; diff --git a/channels/chan_skinny.c b/channels/chan_skinny.c index 90a611bedfc3fb375f9470fe144999c330c41682..44d88ae1f94257c98fc02df27d832dffc7a18d06 100644 --- a/channels/chan_skinny.c +++ b/channels/chan_skinny.c @@ -3650,6 +3650,9 @@ static int skinny_indicate(struct ast_channel *ast, int ind, const void *data, s break; case AST_CONTROL_PROCEEDING: break; + case AST_CONTROL_SRCUPDATE: + ast_rtp_new_source(sub->rtp); + break; default: ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", ind); return -1; diff --git a/channels/chan_unistim.c b/channels/chan_unistim.c index 923d5d4944273fe6d513e894adea0918ab43d626..8adb3497b40d15f6af2a8c252325366398bc2cf3 100644 --- a/channels/chan_unistim.c +++ b/channels/chan_unistim.c @@ -4117,6 +4117,7 @@ static int unistim_indicate(struct ast_channel *ast, int ind, const void *data, ast_moh_stop(ast); break; case AST_CONTROL_PROGRESS: + case AST_CONTROL_SRCUPDATE: break; case -1: ast_playtones_stop(ast); diff --git a/channels/chan_zap.c b/channels/chan_zap.c index 9e73eeffd5519ca1177d5f0813de8eb847e98fca..ea19e9f56ec103dc710791a574fd673c0d39da74 100644 --- a/channels/chan_zap.c +++ b/channels/chan_zap.c @@ -5813,6 +5813,9 @@ static int zt_indicate(struct ast_channel *chan, int condition, const void *data } else res = 0; break; + case AST_CONTROL_SRCUPDATE: + res = 0; + break; case -1: res = tone_zone_play_tone(p->subs[index].zfd, -1); break; diff --git a/include/asterisk/frame.h b/include/asterisk/frame.h index 3206f860f83935c8207e59a9fbc8c47f98fc536a..ad4b8292006bfd3aed303f939ceba2b1b0444f2d 100644 --- a/include/asterisk/frame.h +++ b/include/asterisk/frame.h @@ -83,6 +83,7 @@ struct ast_codec_pref { \arg \b HOLD Call is placed on hold \arg \b UNHOLD Call is back from hold \arg \b VIDUPDATE Video update requested + \arg \b SRCUPDATE The source of media has changed */ @@ -292,7 +293,8 @@ enum ast_control_frame_type { AST_CONTROL_HOLD = 16, /*!< Indicate call is placed on hold */ AST_CONTROL_UNHOLD = 17, /*!< Indicate call is left from hold */ AST_CONTROL_VIDUPDATE = 18, /*!< Indicate video frame update */ - AST_CONTROL_T38 = 19 /*!< T38 state change request/notification */ + AST_CONTROL_T38 = 19, /*!< T38 state change request/notification */ + AST_CONTROL_SRCUPDATE = 20, /*!< Indicate source of media has changed */ }; enum ast_control_t38 { diff --git a/main/channel.c b/main/channel.c index ecb12ac573bc59e3f16f7c714a74c273b6053790..3c68a71b7cb1418a8fba597125c5603cd77f603b 100644 --- a/main/channel.c +++ b/main/channel.c @@ -2745,6 +2745,8 @@ int ast_indicate_data(struct ast_channel *chan, int condition, const void *data, /* Do nothing.... */ } else if (condition == AST_CONTROL_VIDUPDATE) { /* Do nothing.... */ + } else if (condition == AST_CONTROL_SRCUPDATE) { + /* Do nothing... */ } else { /* not handled */ ast_log(LOG_WARNING, "Unable to handle indication %d for '%s'\n", condition, chan->name); @@ -3272,6 +3274,7 @@ struct ast_channel *__ast_request_and_dial(const char *type, int format, void *d case AST_CONTROL_HOLD: case AST_CONTROL_UNHOLD: case AST_CONTROL_VIDUPDATE: + case AST_CONTROL_SRCUPDATE: case -1: /* Ignore -- just stopping indications */ break; @@ -4156,6 +4159,7 @@ static enum ast_bridge_result ast_generic_bridge(struct ast_channel *c0, struct case AST_CONTROL_HOLD: case AST_CONTROL_UNHOLD: case AST_CONTROL_VIDUPDATE: + case AST_CONTROL_SRCUPDATE: ast_indicate_data(other, f->subclass, f->data, f->datalen); break; default: @@ -4318,6 +4322,10 @@ enum ast_bridge_result ast_channel_bridge(struct ast_channel *c0, struct ast_cha ast_set_flag(c0, AST_FLAG_END_DTMF_ONLY); manager_bridge_event(1, 1, c0, c1); + /* Before we enter in and bridge these two together tell them both the source of audio has changed */ + ast_indicate(c0, AST_CONTROL_SRCUPDATE); + ast_indicate(c1, AST_CONTROL_SRCUPDATE); + for (/* ever */;;) { struct timeval now = { 0, }; int to; @@ -4470,6 +4478,10 @@ enum ast_bridge_result ast_channel_bridge(struct ast_channel *c0, struct ast_cha ast_clear_flag(c0, AST_FLAG_END_DTMF_ONLY); ast_clear_flag(c1, AST_FLAG_END_DTMF_ONLY); + /* Now that we have broken the bridge the source will change yet again */ + ast_indicate(c0, AST_CONTROL_SRCUPDATE); + ast_indicate(c1, AST_CONTROL_SRCUPDATE); + c0->_bridge = NULL; c1->_bridge = NULL; diff --git a/main/dial.c b/main/dial.c index 22472a89e433125dc11e4206e0346f7a2128dfb4..688382fb86916e507a9c5a440864a94524eae16d 100644 --- a/main/dial.c +++ b/main/dial.c @@ -422,6 +422,10 @@ static void handle_frame(struct ast_dial *dial, struct ast_dial_channel *channel ast_verb(3, "%s requested a video update, passing it to %s\n", channel->owner->name, chan->name); ast_indicate(chan, AST_CONTROL_VIDUPDATE); break; + case AST_CONTROL_SRCUPDATE: + if (option_verbose > 2) + ast_verbose (VERBOSE_PREFIX_3 "%s requested a source update, passing it to %s\n", channel->owner->name, chan->name); + ast_indicate(chan, AST_CONTROL_SRCUPDATE); case AST_CONTROL_PROCEEDING: ast_verb(3, "%s is proceeding, passing it to %s\n", channel->owner->name, chan->name); ast_indicate(chan, AST_CONTROL_PROCEEDING); diff --git a/main/file.c b/main/file.c index c16f25112e2924cd45069b21a448a33faa38bc15..16fe39e777cd91fd2e624875ac252c957a282263 100644 --- a/main/file.c +++ b/main/file.c @@ -1136,6 +1136,7 @@ static int waitstream_core(struct ast_channel *c, const char *breakon, case AST_CONTROL_RINGING: case AST_CONTROL_ANSWER: case AST_CONTROL_VIDUPDATE: + case AST_CONTROL_SRCUPDATE: case AST_CONTROL_HOLD: case AST_CONTROL_UNHOLD: /* Unimportant */ diff --git a/main/rtp.c b/main/rtp.c index 5be0586c6e3f13673bd275ba387833e317b1feda..433fa2c79a3153654c562737fafa3306eed34759 100644 --- a/main/rtp.c +++ b/main/rtp.c @@ -3376,7 +3376,8 @@ static enum ast_bridge_result bridge_native_loop(struct ast_channel *c0, struct if ((fr->subclass == AST_CONTROL_HOLD) || (fr->subclass == AST_CONTROL_UNHOLD) || (fr->subclass == AST_CONTROL_VIDUPDATE) || - (fr->subclass == AST_CONTROL_T38)) { + (fr->subclass == AST_CONTROL_T38) || + (fr->subclass == AST_CONTROL_SRCUPDATE)) { if (fr->subclass == AST_CONTROL_HOLD) { /* If we someone went on hold we want the other side to reinvite back to us */ if (who == c0) @@ -3615,7 +3616,8 @@ static enum ast_bridge_result bridge_p2p_loop(struct ast_channel *c0, struct ast if ((fr->subclass == AST_CONTROL_HOLD) || (fr->subclass == AST_CONTROL_UNHOLD) || (fr->subclass == AST_CONTROL_VIDUPDATE) || - (fr->subclass == AST_CONTROL_T38)) { + (fr->subclass == AST_CONTROL_T38) || + (fr->subclass == AST_CONTROL_SRCUPDATE)) { /* If we are going on hold, then break callback mode and P2P bridging */ if (fr->subclass == AST_CONTROL_HOLD) { if (p0_callback)