Монитор вызовов с использованием C# TAPI

Мне нужно создать программу для отслеживания активности телефонных звонков. И получить информацию о звонках, например, номер и имя. Я не силен с кодом TAPI и C#, поэтому надеюсь, что кто-нибудь может мне помочь, я в отчаянии.

У меня есть этот код, где я пытаюсь обнаружить доступные устройства и получить информацию от этих устройств при входящем вызове:

using System;
using TAPI3Lib; 
using JulMar.Atapi; 

namespace ConsoleApp1
{
  class Program
  {
    private void tapi_ITTAPIEventNotification_Event(TAPI_EVENT TapiEvent, object pEvent)
    {
        try
        {
            ITCallNotificationEvent cn = pEvent as ITCallNotificationEvent;
            if(cn.Call.CallState == CALL_STATE.CS_CONNECTED)
            {
                string calledidname = cn.Call.get_CallInfoString(CALLINFO_STRING.CIS_CALLEDIDNAME);
                Console.WriteLine("Called ID Name " + calledidname);
                string callednumber = cn.Call.get_CallInfoString(CALLINFO_STRING.CIS_CALLEDIDNUMBER);
                Console.WriteLine("Called Number " + callednumber);
                string calleridname = cn.Call.get_CallInfoString(CALLINFO_STRING.CIS_CALLERIDNAME);
                Console.WriteLine("Caller ID Name " + calleridname);
                string callernumber = cn.Call.get_CallInfoString(CALLINFO_STRING.CIS_CALLERIDNUMBER);
                Console.WriteLine("Caller Number " + callernumber);


            }
        }
        catch(Exception ex)
        {
            Console.WriteLine(ex.ToString());
        }
    }



    static void Main(string[] args)
    {
        TapiManager mgr = new TapiManager("ConsoleApp1");
        mgr.Initialize();

        foreach(TapiLine line in mgr.Lines)
        {
            foreach (string s in line.Capabilities.AvailableDeviceClasses)
                Console.WriteLine("{0} - {1}", line.Name, s);
        }
    }
}
}

Но когда я запускаю его, просто вижу доступные устройства, но не вижу никакой информации о вызовах. Я привык к программированию на Java, поэтому я думаю, что мне следует отправить метод вызова, который получает информацию о вызове в основном, но я не знаю, как это сделать, и в любом коде, который я видел, они это делают. Итак, надеюсь, что вы поможете мне понять, как работает TAPI и что я могу сделать, чтобы мой код работал.

0 ответов

Хорошо, во-первых, вы хотите придерживаться одной версии TAPI. В вашем using операторы, вы импортируете управляемую библиотеку TAPI 2.x и управляемую библиотеку TAPI 3.x.

using TAPI3Lib; // this is a TAPI 3.x library
using JulMar.Atapi; // this is a TAPI 2.x library

Если вы решили использовать TAPI 3.x, вам следует начать с создания нового класса, который обрабатывает различные виды событий TAPI. Для этого необходимо реализовать ITTAPIEventNotification интерфейс:

public class CallNotification : ITTAPIEventNotification
{
    public void Event(TAPI_EVENT TapiEvent, object pEvent)
    {
        if(pEvent == null)
            throw new ArgumentNullException(nameof(pEvent));

        switch (TapiEvent)
        {
            case TAPI_EVENT.TE_CALLNOTIFICATION:
                // This event will be raised every time a new call is created on an monitored line-
                // You can use CALLINFO_LONG.CIL_ORIGIN to see weather it's an inbound call, or an
                // outbound call.
                break;
            case TAPI_EVENT.TE_CALLSTATE:
                // This event will be raised every time the state of a call on one of your monitored
                // Lines changes.
                // If you'd want to read information about a call, you can do it here:
                ITCallStateEvent callStateEvent = (ITCallStateEvent)pEvent;
                ITCallInfo call = callStateEvent.Call;

                string calledidname = call.get_CallInfoString(CALLINFO_STRING.CIS_CALLEDIDNAME);
                Console.WriteLine("Called ID Name " + calledidname);

                string callednumber = call.get_CallInfoString(CALLINFO_STRING.CIS_CALLEDIDNUMBER);
                Console.WriteLine("Called Number " + callednumber);

                string calleridname = call.get_CallInfoString(CALLINFO_STRING.CIS_CALLERIDNAME);
                Console.WriteLine("Caller ID Name " + calleridname);

                string callernumber = call.get_CallInfoString(CALLINFO_STRING.CIS_CALLERIDNUMBER);
                Console.WriteLine("Caller Number " + callernumber);
                break;
        }

        // Since you're working with COM objects, you should release any used references.
        Marshal.ReleaseComObject(pEvent); 
    }
}

Чтобы использовать этот класс, вам нужно создать новый экземпляр TAPI3Lib.TAPIClass и назовите его Initialize метод. После этого вы можете прикрепить свой новый созданный CallNotification Класс как обработчик событий. Вы также можете указать, какие типы событий вы хотите, чтобы ваш обработчик получал. Обратите внимание, что в этот момент вы не будете получать никаких уведомлений о событиях, потому что вы не сказали TAPIClass какие линии он должен отслеживать:

CallNotification callevent = new CallNotification();
TAPIClass tapi = new TAPIClass();
tapi.Initialize();
tapi.EventFilter = (int)(TAPI_EVENT.TE_CALLNOTIFICATION | TAPI_EVENT.TE_CALLSTATE);
tapi.ITTAPIEventNotification_Event_Event += new ITTAPIEventNotification_EventEventHandler(callevent.Event);

Для того, чтобы рассказать TAPIClass какие линии он должен отслеживать, нужно сделать две вещи. запросить все линии, зарегистрированные для вас IPBX, и определить, подходит ли вам линия для мониторинга (это конфигурация IPBX):

public List<ITAddress> EnumerateLines(TAPIClass tapi)
{
    List<ITAddress> addresses = new List<ITAddress>();

    ITAddress address;
    uint arg = 0;

    ITAddressCapabilities addressCapabilities;
    int callfeatures;
    int linefeatures;
    bool hasCallFeaturesDial;
    bool hasLineFeaturesMakeCall;

    IEnumAddress ea = tapi.EnumerateAddresses();

    do
    {
        ea.Next(1, out address, ref arg);

        if (address != null)
        {
            addressCapabilities = (ITAddressCapabilities)address;

            callfeatures = addressCapabilities.get_AddressCapability(ADDRESS_CAPABILITY.AC_CALLFEATURES1);
            linefeatures = addressCapabilities.get_AddressCapability(ADDRESS_CAPABILITY.AC_LINEFEATURES);

            hasCallFeaturesDial = (callfeatures1 & (int)0x00000040) != 0; //Contains LineCallFeatures Dial; see Tapi.h for details
            hasLineFeaturesMakeCall = (linefeatures & (int)0x00000008) != 0; //Contains LineFeatures MakeCall; see Tapi.h for details

            // this is basically saying "Am I allowed to dial numbers and create calls on this specific line?"
            if(hasCallFeaturesDial && hasLineFeaturesMakeCall)
                address.Add(address);
        }
    } while (address != null);

    return addresses;
}

public void RegisterLines(TAPIClass tapi, IEnumerable<ITAddress> addresses)
{
    if (tapi == null)
        throw new ArgumentNullException(nameof(tapi));

    if (addresses == null)
        throw new ArgumentNullException(nameof(addresses));

    foreach (ITAddress address in addresses)
    {
        tapi.RegisterCallNotifications(address, true, true, TapiConstants.TAPIMEDIATYPE_AUDIO, 2);
    }
}

поэтому ваша инициализация будет выглядеть так:

CallNotification callevent = new CallNotification();
TAPIClass tapi = new TAPIClass();
tapi.Initialize();

IEnumerable<ITAddress> addresses = this.EnumerateLines(tapi);
this.RegisterLines(tapi, addresses);

tapi.EventFilter = (int)(TAPI_EVENT.TE_CALLNOTIFICATION | TAPI_EVENT.TE_CALLSTATE);
tapi.ITTAPIEventNotification_Event_Event += new 
ITTAPIEventNotification_EventEventHandler(callevent.Event);

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

Я надеюсь, что вы могли бы следить за этим постом. Если есть вопросы, просто задавайте =)

Линия TapiLine, вы должны использовать TapiCall,

Другие вопросы по тегам