Example #1
1
        static void Main(string[] args)
        {
            try
            {
                // Create a message actionClient to receive events on
                ActionClient = new AriClient(new StasisEndpoint("192.168.3.16", 8088, "username", "test"), AppName);

                ActionClient.OnStasisStartEvent += c_OnStasisStartEvent;
                ActionClient.OnStasisEndEvent += c_OnStasisEndEvent;

                ActionClient.Connect();

                // Create simple bridge
                SimpleBridge = ActionClient.Bridges.Create("mixing", Guid.NewGuid().ToString(), AppName);

                // subscribe to bridge events
                ActionClient.Applications.Subscribe(AppName, "bridge:" + SimpleBridge.Id);

                // start MOH on bridge
                ActionClient.Bridges.StartMoh(SimpleBridge.Id, "default");

                var done = false;
                while (!done)
                {
                    var lastKey = Console.ReadKey();
                    switch(lastKey.KeyChar.ToString())
                    {
                        case "*":
                            done = true;
                            break;
                        case "1":
                            ActionClient.Bridges.StopMoh(SimpleBridge.Id);
                            break;
                        case "2":
                            ActionClient.Bridges.StartMoh(SimpleBridge.Id, "default");
                            break;
                        case "3":
                            // Mute all channels on bridge
                            var bridgeMute = ActionClient.Bridges.Get(SimpleBridge.Id);
                            foreach (var chan in bridgeMute.Channels)
                                ActionClient.Channels.Mute(chan, "in");
                            break;
                        case "4":
                            // Unmute all channels on bridge
                            var bridgeUnmute = ActionClient.Bridges.Get(SimpleBridge.Id);
                            foreach (var chan in bridgeUnmute.Channels)
                                ActionClient.Channels.Unmute(chan, "in");
                            break;
                    }
                }

                ActionClient.Bridges.Destroy(SimpleBridge.Id);
                ActionClient.Disconnect();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
                Console.ReadKey();
            }
        }
Example #2
0
        private static void Main(string[] args)
        {
            try
            {
                // Create a message client to receive events on
                Client = new AriClient(new StasisEndpoint("127.0.0.1", 8088, "username", "test"), AppConfig.AppName);                

                Conference.Conferences.Add(new Conference(Client, Guid.NewGuid(), "test"));
                
                Client.OnStasisStartEvent += c_OnStasisStartEvent;
                Client.OnStasisEndEvent += c_OnStasisEndEvent;

                Client.Connect();

                // Start REST
                WebApp.Start<Startup>(url: AppConfig.RestAddress);
                Console.WriteLine("Loaded... waiting for connections");

                // Wait
                Console.ReadKey();

                // Destroy all the conferences and their bridges
                Conference.Conferences.ForEach(x => x.DestroyConference());
                Conference.Conferences = null;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
                Console.ReadKey();
            }
        }
Example #3
0
        public static PlaybackFinishedEvent Wait(this Playback playback, AriClient client)
        {
            AutoResetEvent _playbackFinished = new AutoResetEvent(false);
            PlaybackFinishedEvent rtn = null;
            client.OnPlaybackFinishedEvent += (s, e) =>
            {
                rtn = e;
                _playbackFinished.Set();
            };

            _playbackFinished.WaitOne();
            return rtn;
        }
Example #4
0
        public ConferenceUser(Conference conf, Channel chan, AriClient client, ConferenceUserType type)
        {
            _conference = conf;
            Channel = chan;
            _client = client;
            Type = type;

            // Initial State
            State = ConferenceUserState.AskForName;
            // Get user to speak name
            CurrentPlaybackId = _client.Channels.Play(Channel.Id, "sound:vm-rec-name", "en", 0, 0, Guid.NewGuid().ToString()).Id;
            RecordName();
        }
        /// <inheritdoc />
        protected override async Task InternalExecute(Channel destinationChannel, StasisStartEventArgs args)
        {
            var routeData = args.RouteData;

            Logger.Information($"AcceptedCallFromUserCommand. DestinationChannelId: {destinationChannel.Id}, UserChannelId: {args.ChannelId}");

            try
            {
                var destinationExtension     = routeData.ToExtension;
                var destinationChannelEntity = await ChannelRepository.GetByChannelId(destinationChannel.Id);

                if (destinationChannelEntity == null)
                {
                    Logger.Warning($"Канал вызываемого участника не найден. ChannelId: {destinationChannel.Id}");
                    return;
                }

                var channelsInBridge = await ChannelRepository.GetByBridgeId(destinationChannelEntity.BridgeId);

                var userChannel = channelsInBridge.SingleOrDefault(x => x.Role == ChannelRoleType.Conference);
                if (userChannel == null)
                {
                    Logger.Warning($"Канал пользователя не найден. LineId: {routeData.LineId}");
                    return;
                }

                var callId = destinationChannelEntity.CallId;

                await StartCallRecording(userChannel.ChannelId, userChannel.CallId, userChannel.Extension, userChannel.Role, userChannel.BridgeId, routeData.LineId);
                await InitializeRecordingChannel(destinationChannel.Id, destinationExtension, destinationChannelEntity.Role, userChannel.BridgeId, callId, routeData.LineId);

                destinationChannelEntity.Role = ChannelRoleType.ExternalChannel;
                await ChannelRepository.UpdateChannel(destinationChannelEntity);

                await AriClient.StopBeeps(args.PlaybackId);

                await AriClient.AddChannelToBridge(userChannel.BridgeId, destinationChannel.Id);

                Logger.Information($"Участник разговора {destinationExtension} принял вызов от пользователя {userChannel.Extension}");
                await _queueSender.Publish(new AcceptCallFromUserIntegrationEvent
                {
                    CallId = callId
                });
            }
            catch (Exception ex)
            {
                Logger.Warning("AcceptedCallFromUserCommand Error", ex);
            }
        }
Example #6
0
        /// <inheritdoc />
        protected override async Task InternalExecute(Channel userChannel, StasisStartEventArgs args)
        {
            Logger.Information($"AcceptIncomingCallCommand. UserChannelId: {userChannel.Id}, IncomingChannelId: {args.ChannelId}");

            try
            {
                var incomingCallChannel = await ChannelRepository.GetByChannelId(args.ChannelId);

                if (incomingCallChannel == null)
                {
                    Logger.Warning($"Канал входящего вызова не найден. UserChannelId: {userChannel.Id}");
                    return;
                }

                var routeData = args.RouteData;
                var lineId    = routeData.LineId;

                await InitializeRecordingChannel(userChannel.Id, routeData.ToExtension, ChannelRoleType.Conference, incomingCallChannel.BridgeId, routeData.ToCallId, lineId);

                await AriClient.UnholdAsync(incomingCallChannel.ChannelId);

                await AriClient.StopMohInBridgeAsync(incomingCallChannel.BridgeId);

                await AriClient.AddChannelToBridge(incomingCallChannel.BridgeId, userChannel.Id);

                incomingCallChannel.Interrupted = false;
                incomingCallChannel.LineId      = lineId;
                await ChannelRepository.UpdateChannel(incomingCallChannel);

                await UpdateAudioRecords(incomingCallChannel.BridgeId, incomingCallChannel.CallId, lineId);

                var userChannelEntity = new DAL.Entities.Channel
                {
                    ChannelId = userChannel.Id,
                    BridgeId  = incomingCallChannel.BridgeId,
                    CallId    = routeData.ToCallId,
                    Extension = routeData.ToExtension,
                    Role      = ChannelRoleType.Conference,
                    LineId    = lineId
                };
                await ChannelRepository.AddChannel(userChannelEntity);
            }
            catch (Exception ex)
            {
                Logger.Warning("AcceptIncomingCallCommand Error", ex);
            }
        }
Example #7
0
        /// <summary>
        /// Создать snoop-копию канала для записи
        /// </summary>
        /// <param name="channelId">Идентификатор исходного канала</param>
        /// <param name="extension">Номер</param>
        /// <param name="role">Роль канала</param>
        /// <param name="forCommonRecord">Признак того, что копия канала создана для записи разговора всех участников в один файл</param>
        /// <param name="callId">Идентификатор звонка</param>
        /// <param name="lineId">Идентификатор линии</param>
        /// <returns>SnoopChannelId</returns>
        private async Task <Result <string> > CreateSnoopChannelForRecording(
            string channelId,
            string extension,
            ChannelRoleType role,
            bool forCommonRecord,
            Guid callId,
            Guid?lineId)
        {
            if (!_asteriskOptions.RecordingEnabled)
            {
                return(Result.Failure(ErrorCodes.RecordingError));
            }

            var routeData = new RouteCallDto
            {
                ToCallId = callId,
                LineId   = lineId
            };

            var snoopChannelId = GetSnoopChannelIdForRecord(role, extension);
            var snoopArgs      = new StasisStartEventArgs
            {
                EventType         = StasisStartEventType.IgnoreStasisEvent,
                ChannelId         = snoopChannelId,
                OriginalChannelId = channelId,
                RouteData         = routeData
            };

            var encodedArgs = JsonSerializer.EncodeData(snoopArgs);
            await AriClient.SnoopChannel(channelId, "in", "none", encodedArgs, snoopChannelId);

            if (forCommonRecord)
            {
                return(Result.Success(snoopChannelId));
            }

            var recordingResult = await StartRecordingChannel(snoopChannelId, callId, lineId);

            if (recordingResult.IsFailure)
            {
                Logger.Information($"CreateSnoopChannelForRecording. StartRecordingChannelError: {recordingResult.ErrorMessage}");
                return(Result.Failure(ErrorCodes.RecordingError));
            }

            return(Result.Success(snoopChannelId));
        }
        private void Start(StasisEndpoint endpoint)
        {
            try
            {
                _logger.Information("Starting Asterisk ARI!");

                var ariClient = new AriClient(endpoint, AppName);
                ariClient.OnConnectionStateChanged += AriClientOnConnectionStateChanged;
                ariClient.Connect();
                _ariClient    = ariClient;
                _endpointHost = endpoint.Host;
            }
            catch (HttpRequestException ex)
            {
                _logger.Error($"Ошибка подключения к Asterisk ARI. Host: {endpoint.Host}:{endpoint.Port}, Endpoint: {endpoint.AriEndPoint}", ex);
                throw;
            }
        }
Example #9
0
        public ConferenceUser(Conference conf, Channel chan, AriClient client, ConferenceUserType type)
        {
            _conference = conf;
            Channel     = chan;
            _client     = client;
            Type        = type;

            // Initial State
            State = ConferenceUserState.AskForName;
            // Get user to speak name
            var playback = _client.Channels.PlayAsync(Channel.Id, "sound:vm-rec-name", "en", 0, 0,
                                                      Guid.NewGuid().ToString());

            playback.Wait();
            CurrentPlaybackId =
                playback.Result.Id;
            RecordName().Wait();
        }
        /// <inheritdoc />
        protected override async Task InternalExecute(Channel channel, StasisStartEventArgs args)
        {
            Logger.Information($"AddToSnoopBridge. Bridge: {args.BridgeId}. Channel: {args.ChannelId}");

            await AriClient.AddChannelToBridge(args.BridgeId, args.ChannelId);

            var channelEntity = new DAL.Entities.Channel
            {
                ChannelId         = args.ChannelId,
                BridgeId          = args.BridgeId,
                Role              = args.EventType == StasisStartEventType.AddToSpeakSnoopBridge ? ChannelRoleType.SpeakSnoopChannel : ChannelRoleType.SnoopChannel,
                LineId            = args.RouteData.LineId,
                CallId            = args.RouteData.ToCallId,
                OriginalChannelId = args.OriginalChannelId,
                Extension         = args.RouteData.ToExtension
            };

            await ChannelRepository.AddChannel(channelEntity);
        }
Example #11
0
        private static void Main(string[] args)
        {
            try
            {
                // Create a new Ari Connection
                ActionClient = new AriClient(new StasisEndpoint("192.168.3.201", 8088, "test", "test"), "HelloWorld");

                // Hook into required events
                ActionClient.OnStasisStartEvent         += c_OnStasisStartEvent;
                ActionClient.OnChannelDtmfReceivedEvent += ActionClientOnChannelDtmfReceivedEvent;
                ActionClient.OnConnectionStateChanged   += ActionClientOnConnectionStateChanged;

                ActionClient.Connect();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
                Console.ReadKey();
            }
        }
Example #12
0
        public Conference( AriClient c, Guid id, string name)
        {
            _client = c;
            Id = id;
            ConferenceName = name;
            State = ConferenceState.Destroyed;

            c.OnChannelDtmfReceivedEvent += c_OnChannelDtmfReceivedEvent;
            c.OnBridgeCreatedEvent += c_OnBridgeCreatedEvent;
            c.OnChannelEnteredBridgeEvent += c_OnChannelEnteredBridgeEvent;
            c.OnBridgeDestroyedEvent += c_OnBridgeDestroyedEvent;
            c.OnChannelLeftBridgeEvent += c_OnChannelLeftBridgeEvent;
            c.OnRecordingFinishedEvent += c_OnRecordingFinishedEvent;

            // Added support for talk detection
            c.OnChannelTalkingStartedEvent += c_OnChannelTalkingStartedEvent;
            c.OnChannelTalkingFinishedEvent += c_OnChannelTalkingFinishedEvent;

            Debug.Print("Added Conference {0}", ConferenceName);
        }
Example #13
0
        public Conference(AriClient c, Guid id, string name)
        {
            _client        = c;
            Id             = id;
            ConferenceName = name;
            State          = ConferenceState.Destroyed;

            c.OnChannelDtmfReceivedEvent  += c_OnChannelDtmfReceivedEvent;
            c.OnBridgeCreatedEvent        += c_OnBridgeCreatedEvent;
            c.OnChannelEnteredBridgeEvent += c_OnChannelEnteredBridgeEvent;
            c.OnBridgeDestroyedEvent      += c_OnBridgeDestroyedEvent;
            c.OnChannelLeftBridgeEvent    += c_OnChannelLeftBridgeEvent;
            c.OnRecordingFinishedEvent    += c_OnRecordingFinishedEvent;

            // Added support for talk detection
            c.OnChannelTalkingStartedEvent  += c_OnChannelTalkingStartedEvent;
            c.OnChannelTalkingFinishedEvent += c_OnChannelTalkingFinishedEvent;

            Debug.Print("Added Conference {0}", ConferenceName);
        }
Example #14
0
        /// <inheritdoc />
        protected override async Task InternalExecute(Channel channel, StasisStartEventArgs args)
        {
            var routeData = args.RouteData;

            if (!routeData.LineId.HasValue)
            {
                return;
            }

            await AriClient.Answer(channel.Id);

            await InitializeRecordingChannel(channel.Id, routeData.ToExtension, ChannelRoleType.Conference, args.BridgeId, routeData.ToCallId, routeData.LineId);

            var bridge = await AriClient.GetBridge(args.BridgeId);

            await AriClient.AddChannelToBridge(bridge.Id, channel.Id);

            await SnoopChannelByAllAssistantsChannels(channel.Id, routeData.ToExtension, ChannelRoleType.Conference, routeData.ToCallId, args);

            Logger.Information($"Channel added to call in conference mode. ChannelId: {channel.Id}. CallId: {routeData.ToCallId}");

            var channelForIncomingCall = await ChannelRepository.GetChannelForIncomingCall(routeData.LineId.Value);

            if (channelForIncomingCall != null && channelForIncomingCall.Interrupted)
            {
                channelForIncomingCall.Interrupted = false;
                await ChannelRepository.UpdateChannel(channelForIncomingCall);
            }

            var channelEntity = new DAL.Entities.Channel
            {
                ChannelId = channel.Id,
                BridgeId  = args.BridgeId,
                CallId    = routeData.ToCallId,
                Extension = routeData.ToExtension,
                Role      = ChannelRoleType.Conference,
                LineId    = routeData.LineId
            };
            await ChannelRepository.AddChannel(channelEntity);
        }
Example #15
0
        /// <summary>
        /// Connecto to Asterisk ARI and WebSocket events
        /// </summary>
        /// <param name="server">IP or host name of asterisk</param>
        /// <param name="port">Port ej: 8088</param>
        /// <param name="usu">ARI user</param>
        /// <param name="pass">ARI password</param>
        public void Connect(string server, int port, string usu, string pass)
        {
            source = server;
            //CREO EL CLIENTE
            pbx = new AriClient(new StasisEndpoint(server, port, usu, pass), appName);
            pbx.EventDispatchingStrategy = EventDispatchingStrategy.DedicatedThread;
            //SUBSCRIBO A EVENTOS
            pbx.OnStasisStartEvent            += Pbx_OnStasisStartEvent;          //Se dispara cuando un canal ejecuta la app stasis en el dialplan. el canal queda ahi a la espera de ser manejado
            pbx.OnStasisEndEvent              += Pbx_OnStasisEndEvent;            //el canal abandonó la app stasis (no quiere decir que cortó)
            pbx.OnChannelHangupRequestEvent   += Pbx_OnChannelHangupRequestEvent; //Se solicito terminar el canal (posee la causa ej: normal clearing)
            pbx.OnChannelStateChangeEvent     += Pbx_OnChannelStateChangeEvent;   //cambió el estado del canal ej: down->up->ringing. No se si lo voy a usar
            pbx.OnChannelDestroyedEvent       += Pbx_OnChannelDestroyedEvent;     //el canal fué terminado, sehizo efectivo el hangup
            pbx.OnChannelHoldEvent            += Pbx_OnChannelHoldEvent;          //el canal se puso onhold
            pbx.OnChannelUnholdEvent          += Pbx_OnChannelUnholdEvent;
            pbx.OnBridgeAttendedTransferEvent += Pbx_OnBridgeAttendedTransferEvent;
            pbx.OnBridgeBlindTransferEvent    += Pbx_OnBridgeBlindTransferEvent;


            //CONECTO EL CLIENTE, true para habilitar reconexion, e intento cada 5 seg
            try
            {
                lock (_locker)
                {
                    Log.Logger.Debug("Conectando call manager en: " + server);
                    pbx.Connect(true, 5);
                    if (pbx.Connected)
                    {
                        List <Bridge> brs = pbx.Bridges.List();
                        foreach (Bridge b in brs)
                        {
                            bridgesList.AddNewBridge(b);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                throw new Exception("Error al conectar con asterisk", ex);
            }
        }
Example #16
0
        private async Task ChangeMainChannel(DAL.Entities.Channel oldMainChannel, DAL.Entities.Channel assistantChannel, Guid lineId, StasisStartEventArgs args)
        {
            var channelsInLine = await ChannelRepository.GetChannelsByLineId(lineId);

            var assistantRole           = assistantChannel.Role;
            var assistantBridgeId       = assistantChannel.BridgeId;
            var mainBridgeId            = oldMainChannel.BridgeId;
            var newMainChannelId        = assistantChannel.ChannelId;
            var newMainChannelExtension = assistantChannel.Extension;

            await AriClient.AddChannelToBridge(mainBridgeId, newMainChannelId);

            await AriClient.AddChannelToBridge(assistantBridgeId, oldMainChannel.ChannelId);

            var assistantSpeakChannel = channelsInLine.SingleOrDefault(t => t.OriginalChannelId == assistantChannel.ChannelId && t.Role == ChannelRoleType.SpeakSnoopChannel);

            if (assistantSpeakChannel != null)
            {
                await InitializeSnoopChannel(oldMainChannel.ChannelId, oldMainChannel.Extension, assistantRole, oldMainChannel.CallId,
                                             assistantSpeakChannel.BridgeId, args, SnoopBridgeType.Speak, true);
            }

            await SnoopChannelByAllAssistantsChannels(newMainChannelId, newMainChannelExtension, ChannelRoleType.MainUser, assistantChannel.CallId, args);

            if (assistantRole == ChannelRoleType.PartialAssistant)
            {
                await SnoopChannelByAllAssistantsChannels(oldMainChannel.ChannelId, oldMainChannel.Extension, assistantRole, oldMainChannel.CallId, args, assistantChannel.ChannelId);
            }

            oldMainChannel.Role       = assistantRole;
            oldMainChannel.BridgeId   = assistantBridgeId;
            assistantChannel.Role     = ChannelRoleType.MainUser;
            assistantChannel.BridgeId = mainBridgeId;
            await ChannelRepository.UpdateChannel(oldMainChannel);

            await ChannelRepository.UpdateChannel(assistantChannel);

            await HangUpOldSnoopChannels(oldMainChannel.ChannelId, channelsInLine);
            await HangUpOldSnoopChannels(newMainChannelId, channelsInLine);
        }
Example #17
0
        /// <inheritdoc />
        protected override async Task InternalExecute(Channel channel, StasisStartEventArgs args)
        {
            var channelId = channel.Id;

            Logger.Information($"RejectedCallFromUserCommand. DestinationChannelId: {channel.Id}");

            try
            {
                var destinationChannel = await ChannelRepository.GetByChannelId(channelId);

                if (destinationChannel == null || destinationChannel.Role != ChannelRoleType.RingingFromUser)
                {
                    Logger.Debug($"RejectedCallFromUserCommand. Канал участника уничтожен. CallId: {destinationChannel?.CallId}. {destinationChannel?.Role}");
                    return;
                }

                await ChannelRepository.DeleteChannel(destinationChannel.ChannelId);

                var channelsInBridge = await ChannelRepository.GetByBridgeId(destinationChannel.BridgeId);

                var userChannel = channelsInBridge.SingleOrDefault(x => x.Role == ChannelRoleType.Conference);
                if (userChannel == null)
                {
                    Logger.Warning("RejectedCallFromUserCommand. Канал пользователя не найден.");
                    return;
                }

                await AriClient.HangupChannel(userChannel.ChannelId);

                Logger.Information($"Отправка информации о том, что участник не принял или отклонил вызов от пользователя. Destination: {destinationChannel.Extension}");
                await _queueSender.Publish(new RejectCallIntegrationEvent
                {
                    CallId = destinationChannel.CallId
                });
            }
            catch (Exception ex)
            {
                Logger.Warning("RejectedCallFromUserCommand Error", ex);
            }
        }
Example #18
0
        /// <summary>
        /// Выполнить команду
        /// </summary>
        protected override async Task InternalExecute(Channel channel, StasisStartEventArgs args)
        {
            var routeData = args.RouteData;

            if (routeData.FromCallId.HasValue)
            {
                var incomingCallChannel = await ChannelRepository.GetChannelByCallId(routeData.FromCallId.Value);

                if (incomingCallChannel != null)
                {
                    incomingCallChannel.Interrupted = true;
                    await ChannelRepository.UpdateChannel(incomingCallChannel);
                }
            }

            var channelForDelete = await ChannelRepository.GetChannelByCallId(routeData.ToCallId);

            if (channelForDelete != null)
            {
                await AriClient.HangupChannel(channelForDelete.ChannelId);
            }
        }
Example #19
0
        private static void Main(string[] args)
        {
            try
            {
                // Create a new Ari Connection
                ActionClient = new AriClient(
                    new StasisEndpoint("192.168.3.201", 8088, "test", "test"),
                    "HelloWorld");

                // Hook into required events
                ActionClient.OnStasisStartEvent += c_OnStasisStartEvent;
                ActionClient.OnChannelDtmfReceivedEvent += ActionClientOnChannelDtmfReceivedEvent;
                ActionClient.OnConnectionStateChanged += ActionClientOnConnectionStateChanged;

                ActionClient.Connect();

                Console.ReadKey();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
                Console.ReadKey();
            }
        }
        /// <summary>
        /// Создать главный бридж, добавить туда канал, включить приветствие ожидания и начать запись
        /// </summary>
        private async Task <string> InitializeMainBridge(string channelId, string callerExtension, Guid initialCallId)
        {
            try
            {
                await AriClient.Answer(channelId);

                var mainBridge = await AriClient.CreateBridge();

                await AriClient.AddChannelToBridge(mainBridge.Id, channelId);

                await StartCallRecording(channelId, initialCallId, callerExtension, ChannelRoleType.ExternalChannel, mainBridge.Id);

                await AriClient.StartMohInBridgeAsync(mainBridge.Id);

                Logger.Information($"InitializeMainBridge. Channel {channelId} added to bridge {mainBridge.Id}");

                return(mainBridge.Id);
            }
            catch (Exception ex)
            {
                Logger.Warning($"InitializeMainBridge Error. {ex.Message}.", ex);
                return(null);
            }
        }
Example #21
0
        /// <summary>
        /// Создать новую пару бриджей (LISTEN/SPEAK) для ассистента/частичного ассистента и добавить туда каналы для прослушивания/разговора
        /// </summary>
        protected async Task <DAL.Entities.Channel> CreateNewAssistantBridgesAndSnoop(Channel assistantChannel,
                                                                                      StasisStartEventArgs args, ChannelRoleType assistantRole)
        {
            var lineId = args.RouteData?.LineId;

            if (!lineId.HasValue)
            {
                Logger.Warning($"CallTo{assistantRole}. LineId не найден AssistantChannelId: {assistantChannel.Id}.");
                return(null);
            }

            var mainChannel = await ChannelRepository.GetChannelForMainUser(lineId.Value);

            if (mainChannel == null)
            {
                Logger.Warning($"CallTo{assistantRole}. MainChannel не найден.");
                return(null);
            }

            var assistantExtension = args.RouteData.ToExtension;
            var assistantCallId    = args.RouteData.ToCallId;
            var prefix             = assistantRole == ChannelRoleType.PartialAssistant ? "PASSISTANT" : "ASSISTANT";
            var assistantBridgeId  = $"{prefix}_{assistantExtension}_{assistantChannel.Id}";
            var speakBridgeId      = $"{assistantBridgeId}_SPEAK";
            var listenBridgeId     = $"{assistantBridgeId}_LISTEN";

            await InitializeRecordingChannel(assistantChannel.Id, args.RouteData.ToExtension, assistantRole, mainChannel.BridgeId, assistantCallId, lineId.Value);

            await AriClient.CreateBridge(speakBridgeId);

            await AriClient.CreateBridge(listenBridgeId);

            await AriClient.AddChannelToBridge(listenBridgeId, assistantChannel.Id);

            await InitializeSnoopChannel(assistantChannel.Id, assistantExtension, assistantRole, assistantCallId, speakBridgeId, args, SnoopBridgeType.Speak, true);

            var channelsInLine = await ChannelRepository.GetChannelsByLineId(lineId.Value);

            var channelsInMainBridge     = channelsInLine.Where(t => t.BridgeId == mainChannel.BridgeId).ToList();
            var partialAssistantChannels = channelsInLine.Where(t => t.Role == ChannelRoleType.PartialAssistant).ToList();

            foreach (var channel in channelsInMainBridge)
            {
                await InitializeSnoopChannel(channel.ChannelId, channel.Extension, channel.Role, channel.CallId, listenBridgeId, args, SnoopBridgeType.Listen);

                if (NeedAddChannelToSpeakBridge(channel.Role, assistantRole))
                {
                    await InitializeSnoopChannel(channel.ChannelId, channel.Extension, channel.Role, channel.CallId, speakBridgeId, args, SnoopBridgeType.Speak);
                }
            }

            foreach (var channel in partialAssistantChannels)
            {
                await InitializeSnoopChannel(channel.ChannelId, channel.Extension, channel.Role, channel.CallId, listenBridgeId, args, SnoopBridgeType.Listen);

                if (assistantRole == ChannelRoleType.PartialAssistant)
                {
                    await InitializeSnoopChannel(channel.ChannelId, channel.Extension, channel.Role, channel.CallId, speakBridgeId, args, SnoopBridgeType.Speak);
                }
            }

            if (assistantRole == ChannelRoleType.PartialAssistant)
            {
                await SnoopChannelByAllAssistantsChannels(assistantChannel.Id, assistantExtension, assistantRole, assistantCallId, args);
            }

            var assistantChannelEntity = new DAL.Entities.Channel
            {
                ChannelId = assistantChannel.Id,
                Extension = assistantExtension,
                CallId    = assistantCallId,
                BridgeId  = listenBridgeId,
                Role      = assistantRole,
                LineId    = lineId.Value
            };
            await ChannelRepository.AddChannel(assistantChannelEntity);

            return(assistantChannelEntity);
        }
Example #22
0
        static void Main(string[] args)
        {
            try
            {
                // Create a message actionClient to receive events on
                ActionClient = new AriClient(new StasisEndpoint("192.168.3.16", 8088, "username", "test"), AppName);

                ActionClient.OnStasisStartEvent += c_OnStasisStartEvent;
                ActionClient.OnStasisEndEvent   += c_OnStasisEndEvent;

                ActionClient.Connect();

                // Create simple bridge
                SimpleBridge = ActionClient.Bridges.Create("mixing", Guid.NewGuid().ToString(), AppName);

                // subscribe to bridge events
                ActionClient.Applications.Subscribe(AppName, "bridge:" + SimpleBridge.Id);

                // start MOH on bridge
                ActionClient.Bridges.StartMoh(SimpleBridge.Id, "default");

                var done = false;
                while (!done)
                {
                    var lastKey = Console.ReadKey();
                    switch (lastKey.KeyChar.ToString())
                    {
                    case "*":
                        done = true;
                        break;

                    case "1":
                        ActionClient.Bridges.StopMoh(SimpleBridge.Id);
                        break;

                    case "2":
                        ActionClient.Bridges.StartMoh(SimpleBridge.Id, "default");
                        break;

                    case "3":
                        // Mute all channels on bridge
                        var bridgeMute = ActionClient.Bridges.Get(SimpleBridge.Id);
                        foreach (var chan in bridgeMute.Channels)
                        {
                            ActionClient.Channels.Mute(chan, "in");
                        }
                        break;

                    case "4":
                        // Unmute all channels on bridge
                        var bridgeUnmute = ActionClient.Bridges.Get(SimpleBridge.Id);
                        foreach (var chan in bridgeUnmute.Channels)
                        {
                            ActionClient.Channels.Unmute(chan, "in");
                        }
                        break;
                    }
                }

                ActionClient.Bridges.Destroy(SimpleBridge.Id);
                ActionClient.Disconnect();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
                Console.ReadKey();
            }
        }