Надежная идентификация и отслеживание вызовов Asterisk с использованием C# и Aster.NET

Я создавал настольное приложение WinForms с использованием С#, которое взаимодействует с Asterisk с использованием Aster.NET (ранее/разветвленного от Asterisk.NET). У нас серьезные проблемы с надежной идентификацией и отслеживанием вызовов, связанных с отдельным добавочным номером/пользователем.

Проблема, с которой мы сталкиваемся, связана с непредсказуемым/нечетким характером событий, запускаемых/инициируемых Asterisk, причем они сильно варьируются в зависимости от того, как маршрутизируется вызов до того, как он попадет на добавочный номер.

Например, последовательность/формат событий различаются, когда: вызов попадает в IVR до того, как его переводят вслепую; если вызов поступает в IVR до того, как он будет переведен; если вызов идет прямо на добавочный номер пользователя.

Этому также препятствует то, что Asterisk отслеживает каждую сторону вызова, используя разные уникальные идентификаторы (например, входящая сторона вызова имеет другой UID, чем полученная сторона вызова). Хотя нам удалось учесть это в (впоследствии уродливом!) коде, мы все еще сталкиваемся с проблемами учета различных путей маршрутизации, которые может пройти вызов.

Таким образом, я ищу любые советы о том, как мы можем сделать следующее:

  1. Reliably identify an incoming call to a user's extension
    • We need to be able to identify the extension being called and the originating caller ID (after either a blind or attended transfer and direct call from external)
    • Надежно отслеживайте уникальный идентификатор входящего звонка, поскольку он используется для ссылки на запись звонка.
  2. Reliably identify an outgoing call from a user's extension
    • With the same caveats as above in mind

На данный момент у нас есть чрезвычайно сложная цепочка обработчиков событий, которые работают по-разному в зависимости от «текущего состояния» приложения.

Приведу один пример: если мы обнаруживаем NewStateEvent с ChannelState равным 6 ("Up"), мы проверяем, есть ли текущий вызов в процессе и совпадают ли UID, и если да, то текущий на звонок ответили. Если UID не совпадают, но совпадают другие факторы (например, канал, connectlinenum и т. д.), то мы рассматриваем это как «другую сторону» вызова (т. е. принимающую или входящую сторону).

Я не уверен, связана ли проблема с API или с AMI, но в любом случае это вызывает у нас настоящую головную боль.

Любые советы очень ценятся.


person iam    schedule 30.01.2014    source источник


Ответы (2)


Можно ли обновиться до Asterisk 12? Имена каналов в AMI теперь стабильны в Asterisk 12.

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

person sruffell    schedule 01.02.2014
comment
Извините, я только что увидел этот ответ, и это именно то, что я искал в эти выходные после того, как наткнулся на примечания к выпуску Asterisk 12. Единственная проблема, с которой я столкнулся, заключается в том, что обновление до Asterisk 12 сломает AsteriskNOW и его подсистемы, я не могу найти абсолютно нулевую документацию (т. е. сообщения в блогах, сообщения на форуме и т. - person iam; 03.02.2014
comment
Если вы используете AsteriskNOW, я думаю, вам нужно подождать, пока FreePBX (который является пользователями AsteriskNOW с графическим интерфейсом) будет обновлен для поддержки Asterisk 12. Эта работа почти завершена. blogs.digium.com/2014/01/14/freepbx -12-скоро - person sruffell; 03.02.2014
comment
Большое спасибо, я только что получил ответ от одного из разработчиков Asterisk, говорящего почти то же самое. Думаю, это случай зависания огня, пока FreePBX/AsteriskNOW не наверстает упущенное! - person iam; 04.02.2014

я использую пакет 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...");



            }

        }
person Aamir Hussain    schedule 23.09.2019