使用C#和Aster.NET可靠地识别和跟踪Asterisk调用

时间:2014-01-30 14:43:05

标签: c# asterisk asteriskami

我一直在使用C#构建一个WinForms桌面应用程序,它使用Aster.NET(以前/从Asterisk.NET派生)与Asterisk连接。我们在可靠地识别和跟踪与单个分机/用户相关的呼叫方面遇到了麻烦。

我们遇到的问题是由于Asterisk发起/触发的事件具有不可预测/模糊的特性,根据呼叫在到达扩展名之前的路由方式,它们会发生巨大变化。

例如,事件序列/格式在以下情况下是不同的:呼叫在盲目转移之前命中IVR;如果一个电话在转发之前就打到了IVR;如果通话直接转到用户的分机号。

Asterisk使用不同的唯一ID跟踪呼叫的每一侧的方式进一步阻碍了这一点(例如,呼叫的呼入侧具有与呼叫的接收侧不同的UID)。虽然我们已经设法在(随后丑陋的!)代码中解释了这一点,但我们仍然遇到了考虑调用可以采用的不同路由路径的问题。

因此,我正在寻找有关如何执行以下操作的任何建议:

  1. 可靠地识别对用户分机的来电
    • 我们需要能够识别被呼叫的分机和始发来电显示(在盲人或有人转接和外部直接呼叫之后)
    • 可靠地跟踪该来电的唯一ID,因为它用于链接到通话记录
  2. 可靠地识别来自用户分机的拨出电话
    • 与上述相同的警告
  3. 因为我们现在有一个非常复杂的事件处理程序链,它们的运行方式取决于应用程序的“当前状态”。

    举一个例子:如果我们检测到ChannelState为6('Up')的NewStateEvent,我们会检查进程中是否有正在进行的调用UID匹配,如果是那时当前的电话已经回答了。如果UID不匹配,但其他因素(例如频道,连接线等),则我们将其选为呼叫的“另一侧”(即接收侧或接收侧)。

    我不确定API或AMI是否存在问题 - 但不管它是什么导致我们一些真正的麻烦。

    任何建议都非常感谢。

2 个答案:

答案 0 :(得分:2)

您是否可以更新到Asterisk 12? AMI中的频道名称现在在Asterisk 12中稳定。

https://wiki.asterisk.org/wiki/display/AST/AMI+v2+Specification

答案 1 :(得分:1)

我在c#中使用软件包Aster.NET。首先安装最新版本的aster.net
而不是检查该代码。此代码对我来说很完美。

        manager = new ManagerConnection(address, port, user, password);
        manager.UnhandledEvent += new ManagerEventHandler(manager_Events);
        manager.NewState += new NewStateEventHandler(Monitoring_NewState);
        try
        {
            // Uncomment next 2 line comments to Disable timeout (debug mode)
            // manager.DefaultResponseTimeout = 0;
            // manager.DefaultEventTimeout = 0;


            manager.Login();

            if (manager.IsConnected())
            {



                Console.WriteLine("user name  : " + manager.Username);






                Console.ReadLine();

            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("Error connect\n" + ex.Message);
            manager.Logoff();
            Console.ReadLine();

        }
        void manager_Events(object sender, ManagerEvent e)
        {
            Console.WriteLine("Event : " + e.GetType().Name);

        }

           void Monitoring_NewState(object sender, NewStateEvent e)
              {
            string state = e.State;
            string callerID = e.CallerId;

            Console.WriteLine("caller  num ...", e.CallerIdNum);

            //Console.WriteLine("state =", state);

            //Console.WriteLine("callerID =", callerID);



            if ((state == "Ringing") | (e.ChannelState == "5"))
            {

                Console.WriteLine("hello rining your phone now ...");

                String connectedLineNum;
                String connectedLineName;

                Dictionary<String, String> attributes = e.Attributes;

                attributes.TryGetValue("connectedlinenum", out connectedLineNum);
                attributes.TryGetValue("connectedlinename", out connectedLineName);
                // "callerID" - called phone number
                // "connectedLineNum" - calling phone number



                // CallIn. Incoming call
            }
            else if ((state == "Ring") | (e.ChannelState == "4"))
            {

                Console.WriteLine("hello out going your call ...");
                // CallOut. Outcoming call
            }
            else if ((state == "Up") | (e.ChannelState == "6"))
            {
                String connectedLineNum;
                String connectedLineName;


                Dictionary<String, String> attributes = e.Attributes;

                attributes.TryGetValue("connectedlinenum", out connectedLineNum);
                attributes.TryGetValue("connectedlinename", out connectedLineName);
                // "callerID" - called phone number
                // "connectedLineNum" - calling phone number

                // human lifted up the phone right no

                Console.WriteLine("human lifted up the phone...");



            }

        }