通过传输Tapi3识别连接到我的呼叫

时间:2018-02-13 15:41:00

标签: c# pbx tapi

我已经能够创建一个应用程序(ab)使用TAPI3Lib并理解来电,将它们置于保持状态,振铃内部号码,将保留的线路与目标号码连接起来。

以下是获取来电号码的代码

     private void tapi_ITTAPIEventNotification_Event_Event(TAPI3Lib.TAPI_EVENT TapiEvent, object pEvent)
     {
        try
        {

            switch (TapiEvent)
            {
                case TAPI3Lib.TAPI_EVENT.TE_CALLNOTIFICATION:
                    TAPI3Lib.ITCallNotificationEvent cln = pEvent as TAPI3Lib.ITCallNotificationEvent;
                    if (cln.Call.CallState == TAPI3Lib.CALL_STATE.CS_OFFERING)
                    {
                        string c = cln.Call.get_CallInfoString(TAPI3Lib.CALLINFO_STRING.CIS_CALLERIDNUMBER);
                        string target = cln.Call.Address.DialableAddress;
                    .
                    .
                    .

在这里,我对数据库运行MSSQL查询,以确定谁是该号码的所有者。我在屏幕上显示一个正在呼叫的潜在用户的表单。表单上的按钮允许您拨打内部号码(此操作会自动添加当前线路。

    IEnumCall ec = ia[line].EnumerateCalls();
        uint arg = 0;
        ITCallInfo ici;

        try
        {
            ec.Next(1, out ici, ref arg);
            ITBasicCallControl bc = (ITBasicCallControl)ici;
            bc.Hold(true);

        }
        catch (Exception exp)
        {
            System.Windows.Forms.MessageBox.Show("May not have any call to put on hold!\n\n" + exp.ToString(), "TAPI3");
        }

        IEnumCall ec1 = ia[line].EnumerateCalls();
        uint arg1 = 0;
        ITCallInfo ici1;

        try
        {
            ec1.Next(1, out ici1, ref arg1);
            ITBasicCallControl bc1 = ia[line].CreateCall("107",TapiConstants.LINEADDRESSTYPE_IPADDRESS, TapiConstants.TAPIMEDIATYPE_AUDIO);
            bc1.Connect(false);


        }
        catch (Exception exp)
        {
            System.Windows.Forms.MessageBox.Show("Target looks unreachable!\n\n" + exp.ToString(), "TAPI3");
        }

此部分将当前活动行与保持行连接;

    ITBasicCallControl callOnHold = null;
        ITBasicCallControl callConnected = null;
        IEnumCall enumCall = ia[line].EnumerateCalls();
        ITCallInfo callInfo;
        uint dummy = 0;
        while (true)
        {
            enumCall.Next(1, out callInfo, ref dummy);
            if (callInfo == null)
                return;
            if (callInfo.CallState == CALL_STATE.CS_HOLD)
                callOnHold = (ITBasicCallControl)callInfo;
            else if (callInfo.CallState == CALL_STATE.CS_CONNECTED)
                callConnected = (ITBasicCallControl)callInfo;
            if (callOnHold != null && callConnected != null)
                break;
        }

        callOnHold.Transfer(callConnected, true); 
        callConnected.Finish(FINISH_MODE.FM_ASTRANSFER);

启动如下;

    ITAddress[] ia = new TAPI3Lib.ITAddress[10]; 
    ...
    try
        {
            tobj = new TAPIClass();
            tobj.Initialize();
            IEnumAddress ea = tobj.EnumerateAddresses();
            ITAddress ln;
            uint arg3 = 0;
            lines = 0;

            cn = new callnotification();

            tobj.ITTAPIEventNotification_Event_Event += new TAPI3Lib.ITTAPIEventNotification_EventEventHandler(cn.Event);
            tobj.EventFilter = (int)(TAPI_EVENT.TE_CALLNOTIFICATION |
                TAPI_EVENT.TE_DIGITEVENT |
                TAPI_EVENT.TE_PHONEEVENT |
                TAPI_EVENT.TE_CALLSTATE |
                TAPI_EVENT.TE_GENERATEEVENT |
                TAPI_EVENT.TE_GATHERDIGITS |
                TAPI_EVENT.TE_REQUEST);

            for (int i = 0; i < 10; i++)
            {
                ea.Next(1, out ln, ref arg3);
                ia[i] = ln;
                if (ln != null)
                {
                   lines++;
                }
                else
                    break;
            }
        }
        catch (Exception e)
        {
            System.Windows.Forms.MessageBox.Show(e.ToString());
        }

- 方案

CallA :来电

CallB :内部通话

运营商:主要应答运营商

Bob :此应用程序的用户

Alice :CallA的来电者

Bob 使用手机拨打 Alice 的呼叫中心。 运营商会看到一个包含 Bob 的名称和号码的弹出式屏幕,然后拿起电话。 ( CallA 已存储)。 Bob 要求与 Alice 交谈。 运营商点击屏幕上的“ Alice ”( CallA 现已暂停,运营商的手机创建 CallB ,响起 Alice 的电话。 Alice 接听该线路并同意接听电话。 运营商点击屏幕上的“转移”, CallA CallB 已连接。

- 情景结束

- 预期结果

运营商呼叫 Alice 时,该事件会看到100被称为107(100为PBX上的运营商的地址, 107 Alice 。当运营商连接2个电话时,我希望能够弹出与运营商相同的屏幕其中包括已连接的来电者的信息。为了解雇该事件,我错过了什么?因为当我尝试检查cln.Call.get_CallInfoString(TAPI3Lib.CALLINFO_STRING.CIS_CALLERIDNUMBER)时,我看到的是100,这是操作员 Alice ,这是正确的。为了识别呼叫已被转移,我需要做什么检查→获取来电显示→弹出屏幕

- 预期结果结束

我希望我能够描述它,因为我有它的想法。感谢您的时间,请原谅我这篇冗长的帖子。

3 个答案:

答案 0 :(得分:0)

TAPI3 lib可能有一些不同的命名,但您正在寻找的字段在TAPI本身上称为ConnectedId,RedirectingId和RedirectionId。 但是,无论这些字段是否填满,它都非常依赖于PBX本身。

在“理论上”的转移呼叫场景中,您应该在呼叫信息中看到这一点:

  • 来电显示:原始来电的来源(=客户)
  • 被叫id:原始呼叫的目的地(=公司或服务的公布号码)
  • 已连接的ID:实际当前对方(=您正在与之对话)
  • 重定向ID:将呼叫转移给您的号码(=运营商分机号)
  • 重定向ID:重定向方(=运营商)转移呼叫的号码,“应该”是您正在观察此设备的设备(如果不涉及进一步转发)

但是TAPI没有强制执行这项工作,所以PBX可以填写它想要的东西,不同的供应商会:(

答案 1 :(得分:0)

按照Kris Vanherck的建议,我做了一个临时措施来处理转移,直到我们找到合适的解决方案;

     string con="000";
                            while (con.Length ==3 && con.Length >=3)
                            {

                                con = cln.Call.get_CallInfoString(TAPI3Lib.CALLINFO_STRING.CIS_CONNECTEDIDNUMBER);
                            }

愚蠢的方法,但嘿它的工作原理。迫不及待地想要找到更合适的方法来做到这一点。再次感谢Kris的指导。

答案 2 :(得分:0)

你自己太难了。您无需手动调用Hold,Transfer方法会为您执行此操作。

当来自B的新来电(TAPI_EVENT.TE_CALLNOTIFICATION)进来时,您可以将其ITBasicCallControl拨打Transfer

case TAPI_EVENT.TE_CALLNOTIFICATION:
  ITBasicCallControl incomingCall = callNotification.Call;
  break;

Transfer方法指向新创建的调用呼叫,因此请务必事先创建新呼叫:

//In this case address is of type ITAddress and represents the operators address.
ITBasicCallControl consultationCall = address.CreateCall("107", TapiConstants.LINEADDRESSTYPE_PHONENUMBER, TapiConstants.TAPIMEDIATYPE_AUDIO);

现在您可以致电转移:

incomingCall.Transfer(consultationCall, false);

最后,当咨询电话断开连接并且Alice想要接听电话时,请使用Finish方法完成转接:

case CALL_STATE.CS_DISCONNECTED:
  ITBasicCallControl consultationCall = (ITBasicCallControl )callStateEvent.Call;
  consultationCall.Finish(FINISH_MODE.FM_ASTRANSFER);
  break;