Exemple #1
0
        /// <summary>
        /// Renders the high-level switch action instance into zero or more <see cref="SwitchExecuteAction" />
        /// instances and then adds these to the <see cref="ActionRenderingContext" />.<see cref="ActionRenderingContext.Actions" />
        /// collection.
        /// </summary>
        /// <param name="context">The action rendering context.</param>
        /// <exception cref="NotSupportedException">Thrown for parameters that are not supported for the current execution context.</exception>
        /// <remarks>
        /// <note>
        /// It is perfectly reasonable for an action to render no actions to the
        /// context or to render multiple actions based on its properties.
        /// </note>
        /// </remarks>
        public override void Render(ActionRenderingContext context)
        {
            if (callID1 != Guid.Empty && callID2 != Guid.Empty)
            {
                context.Actions.Add(new SwitchExecuteAction("uuid_bridge", "{0:D} {1:D}", callID1, callID2));
                return;
            }

            // Special case FreeSWITCH style dialstrings.

            if (dialstring != null)
            {
                if (context.IsDialplan)
                {
                    context.Actions.Add(new SwitchExecuteAction("bridge", dialstring));
                }
                else
                {
                    context.Actions.Add(new SwitchExecuteAction(CallID, "bridge", dialstring));
                }

                return;
            }

            if (endpoints.Count == 0)
            {
                throw new InvalidOperationException("Attempt to render a BridgeAction with no endpoints.");
            }

            // Add an action queue any DTMF digits.

            if (queuedDtmfDigits != null && queuedDtmfDigits.Length > 0)
            {
                var duration = ToneDuration;

                if (duration < Switch.MinDtmfDuration)
                {
                    duration = Switch.MinDtmfDuration;
                }
                else if (duration > Switch.MaxDtmfDuration)
                {
                    duration = Switch.MaxDtmfDuration;
                }

                if (context.IsDialplan)
                {
                    context.Actions.Add(new SwitchExecuteAction("queue_dtmf", "{0}@{1}", queuedDtmfDigits, (int)duration.TotalMilliseconds));
                }
                else
                {
                    context.Actions.Add(new SwitchExecuteAction(CallID, "queue_dtmf", "{0}@{1}", queuedDtmfDigits, (int)duration.TotalMilliseconds));
                }
            }

            // Add any propety variables to the variables collection.

            if (AnswerTimeout.HasValue)
            {
                Variables["call_timeout"] = SwitchHelper.GetScheduleSeconds(AnswerTimeout.Value).ToString();
            }

            if (BypassMedia.HasValue)
            {
                Variables["bypass_media"] = BypassMedia.Value ? "true" : "false";
            }

            if (Ringback.HasValue && Ringback.Value)
            {
                Variables["ringback"] = "${us-ring}";
            }

            if (CallerIDName != null)
            {
                Variables["effective_caller_id_name"] = CallerIDName;
            }

            if (CallerIDNumber != null)
            {
                Variables["effective_caller_id_number"] = CallerIDNumber;
            }

            // I'm not going to use the FreeSWITCH global channel variable syntax {..} at the beginning of
            // the dialstring since this is really just a human friendly shortcut.  Instead, I'm going
            // to explicitly add any global variables that aren't overridden to each endpoint.

            if (Variables.Count > 0)
            {
                foreach (var endpoint in Endpoints)
                {
                    foreach (var variable in Variables)
                    {
                        if (!endpoint.Variables.ContainsKey(variable.Key))
                        {
                            endpoint.Variables[variable.Key] = variable.Value;
                        }
                    }
                }
            }

            // Render the dialstring if there's only one endpoint.

            if (endpoints.Count == 1)
            {
                if (context.IsDialplan)
                {
                    context.Actions.Add(new SwitchExecuteAction("bridge", endpoints[0].ToString()));
                }
                else
                {
                    context.Actions.Add(new SwitchExecuteAction(CallID, "bridge", endpoints[0].ToString()));
                }

                return;
            }

            // We have multiple endpoints so we need to render based on the bridge mode.

            var sb = new StringBuilder();

            switch (Mode)
            {
            case BridgeMode.LinearHunt:

                foreach (var endpoint in endpoints)
                {
                    sb.AppendFormat("{0},", endpoint);
                }

                break;

            case BridgeMode.RandomHunt:

                endpoints.Shuffle();
                foreach (var endpoint in endpoints)
                {
                    sb.AppendFormat("{0},", endpoint);
                }

                break;

            case BridgeMode.RingAll:

                foreach (var endpoint in endpoints)
                {
                    sb.AppendFormat("{0}|", endpoint);
                }

                break;
            }

            if (sb.Length > 0)
            {
                sb.Length--;
            }

            if (context.IsDialplan)
            {
                context.Actions.Add(new SwitchExecuteAction("bridge", sb.ToString()));
            }
            else
            {
                context.Actions.Add(new SwitchExecuteAction(CallID, "bridge", sb.ToString()));
            }
        }