1

I write an IVR program with tapiex activex v3.6 and i want to get multi-calls per line but in my program when the program is in call and i want to call it at the same time, it is busy! what should i do? should i put the connected call in on hold? if yes when i have to do this? when the program is in call and someone try to call it at the same time, will an event fired up? if yes which event? should my program be multi-thread? i tried to make it multi-thread but this error happened!

'COM object that has been separated from its underlying RCW cannot be used.'

StartIvr();
//UiGlobal.ThreadManager.StartThread(o => StartIvr());

this is my startIvr method

private void StartIvr()
        {
            UI.Class.IVR.EventHandler eventHandler = new Class.IVR.EventHandler();
            eventHandler.InitPhone();
            eventHandler.OpenLine(null);
            UiGlobal.eventHandler = eventHandler;
        }

and this is my event handler class

class EventHandler
{
    public List<string> linesName { get; set; }
    public AxTAPIEXLib.AxTAPIExCtl Tapiex_com { get; set; }
    public bool IsOutputCall = false;
    CallHandler callHandler;


    public EventHandler()
    {
        linesName = new List<string>();
        Tapiex_com = new AxTAPIEXLib.AxTAPIExCtl();

    }

    public EventHandler(AxTAPIEXLib.AxTAPIExCtl Tapiex_com)
    {
        linesName = new List<string>();
        this.Tapiex_com = Tapiex_com;
    }

    public ITAPILine Find_line(string LineName)
    {
        ITAPILine line = null;
        for (int i = 0; i < Tapiex_com.Lines.Count; i++)
            if (Tapiex_com.Lines.Item(i).Name == LineName)
            {
                line = Tapiex_com.Lines.Item(i);
                break;
            }
        return line;

    }
    protected void Dispose(bool disposing)
    {
        if (disposing && (Tapiex_com != null))
        {
            Tapiex_com.Dispose();
        }
    }
    public bool InitPhone()
    {
        Tapiex_com.CreateControl();
        Tapiex_com.OnRing += new AxTAPIEXLib._ITAPIExEvents_OnRingEventHandler(this.Tapiex_com_OnRing);
        Tapiex_com.OnDTMF += new AxTAPIEXLib._ITAPIExEvents_OnDTMFEventHandler(this.Tapiex_com_OnDTMF);
        Tapiex_com.OnConnected += new AxTAPIEXLib._ITAPIExEvents_OnConnectedEventHandler(this.Tapiex_com_OnConnected);
        Tapiex_com.OnDisConnected += new AxTAPIEXLib._ITAPIExEvents_OnDisConnectedEventHandler(this.Tapiex_com_OnDisConnected);
        Tapiex_com.OnCallerID += new AxTAPIEXLib._ITAPIExEvents_OnCallerIDEventHandler(this.Tapiex_com_OnCallerID);
        Tapiex_com.OnNewCall += new AxTAPIEXLib._ITAPIExEvents_OnNewCallEventHandler(this.Tapiex_com_OnNewCall);
        bool init = Tapiex_com.initialize();

        foreach (ITAPILine tmpline in Tapiex_com.Lines)
            if ((tmpline.Caps.Media_Modes & LINEMEDIAMODE.MEDIAMODE_INTERACTIVEVOICE) > 0 ||
                (tmpline.Caps.Media_Modes & LINEMEDIAMODE.MEDIAMODE_AUTOMATEDVOICE) > 0)
                linesName.Add(tmpline.Name);
        return init;
    }

    public bool OpenLine(string lineName)
    {
        if (lineName == null)
        {
            foreach (string item in linesName)
            {
                var line = Find_line(item);
                if (!line.Opened)
                    line.Open();
            }
            return true;
        }
        else
        {
            var line = Find_line(lineName);
            if (line != null)
            {
                if (!line.Opened)
                    line.Open();
                return true;
            }
            else return false;
        }

    }
    private void Tapiex_com_OnDTMF(object sender, _ITAPIExEvents_OnDTMFEvent e)
    {
        if (!IsOutputCall)
        {
            isInDTMFMethod = true;
            callHandler.DTMF(e);
            isInDTMFMethod = false;
        }
    }
    private void Tapiex_com_OnNewCall(object sender, _ITAPIExEvents_OnNewCallEvent e)
    {
        callHandler = new CallHandler();
    }

    private void Tapiex_com_OnRing(object sender, AxTAPIEXLib._ITAPIExEvents_OnRingEvent e)
    {
        if (e.ringCount > 1) e.m_Call.Answer();
    }

    private void Tapiex_com_OnConnected(object sender, AxTAPIEXLib._ITAPIExEvents_OnConnectedEvent e)
    {
        callHandler.Connected(e, IsOutputCall);

    }

    private void Tapiex_com_OnDisConnected(object sender, AxTAPIEXLib._ITAPIExEvents_OnDisConnectedEvent e)
    {
        callHandler.HangUp(e.m_Call);
        IsOutputCall = false;
    }

    private void Tapiex_com_OnCallerID(object sender, AxTAPIEXLib._ITAPIExEvents_OnCallerIDEvent e)
    {
        callHandler.GetCallerID(e);
    }
hassan dusti
  • 19
  • 1
  • 4
  • 1
    Welcome to Stack Overflow. Please show your latest non-working attempt at solving this problem. It is usually more instructive to see fixes to your code than to read someone else's solution. See https://stackoverflow.com/help/how-to-ask – Spangen Jun 26 '18 at 07:34

2 Answers2

0

Ok, that is a lot of questions in one post. My apologies if this lack a "practical" answer, but I would need several pages to cover all your items. So I'll make some general observation here in the hope it helps you narrow it down a bit.

1) Multiple lines on a device is not "normal" or "average" behavior, it is also not something TAPI gets to decide over, it is completely up to the PBX system. Most will only allow 1 call on an extension, some 2 and a few exceptions will allow more with special configuration settings. A device, as mostly is understood in TAPI is meant to represent an physical phone device. What an IVR generally will use is a "Trunk Line", but many PBX will not publish/expose those lines via TAPI.

2) ActiveX and COM need to be handled differently in multi threaded environment: different startup and stop functions. You might want to look for a tutorial or book on multi-threaded COM programming first.

3) TAPI primary focus is on monitoring and controlling extension, it's not really suited to support an IVR. I'm not saying it is impossible, but it is definitely the "hard way". In a contact center environment, TAPI is generally used to monitor the call after it has left the IVR, not for the IVR itself. You may want to consider building an IVR on a SIP, H323 or middle-ware stack instead.

4) If you're determined to do TAPI, I would recommend against a TAPI 3 implementation. TAPI 3 was an attempt to bring TAPI into the modern world (of 1999) and did not take everything, so there is a lot of missing bits. The technologies used are by now themselves out of date or deprecated. If you are serious in building something as complex as a commercial IVR system, you may wish to use a TAPI 2 based system, for a more complete and stable interface (and there are some .NET wrappers out there if you're not into native C/C++ coding). It is counter intuitive but 2 is better and bigger then 3 in this case. Especially since you'll need the more "exotic" parts like audio handling (something very few PBX support!) to make an IVR.

Kris Vanherck
  • 245
  • 1
  • 10
  • Do i need a central machine to get several simultaneous calls on one line? – hassan dusti Jun 26 '18 at 16:01
  • no i don't want multiple lines on a device i want multiple simultaneous calls on a line! do i needed special hardware for this task? i have a zoltrix 3chip 56k modem. can i do this with this modem and an analog phone line? – hassan dusti Jun 27 '18 at 08:20
  • Analogue is 1 signal on 1 line = 2 copper wires. Also analogue is very difficult to control, you would need to work directly on the modem serial connection to control an analogue line. Because you'll need things like half length timings (exact terminology escapes me) to get the hook flashes right. I'm sorry this is beyond my ability to help. This is highly specialized information even in the telephony sector, i doubt you'll find what you need on a general programming website. You may wish to search for a dedicated website or newsgroup. – Kris Vanherck Jun 28 '18 at 13:51
0

First, a voice modem is the worst possible telephony device. You will never get it working the way you want. Yes, you can use "hook flash" connected to an analog line to use call waiting or a 3-way call, but you have no control or reporting on the calls. You will have no idea if it worked and what call you are really on. See this: http://www.exceletel.com/products/TeleTools/Help/Working_With_Modems.htm. SOLUTION: Get a Way2Call Hi-Phone for analog, or better, a VoIP provider and use the SIP Communications Server software to connect your SIP trunk to TAPI (2 minute install). Lastly, you could install a "free" PBX like 3CX or Asterisk and connect it to analog lines or a SIP Trunk and install the TSP for the PBX on your machine to control it.

The first answer is full of a lot of misinformation (apologies Kris). First, TAPI is not designed to "respresent a physical phone device". TAPI can control "line devices", "phone devices", "terminal devices" and access to wave, fax, and other devices. It is used most often to control "lines". It has full control over whatever functions are exposed by the manufacturer of the device(s). TAPI is certainly capable of supporting a multi-line IVR. That is part of what Intel and Microsoft designed it to do. Item number 3 above is completely incorrect. Here is a sample of a 4 line IVR program using only a few lines of code with TAPI controls: http://www.exceletel.com/products/TeleTools/SamplePrograms/etIVR4Line/Index.htm. You would need a device that exposes more than one line of course for you to test more than one line at a time.

If you look at that code, you may be able to translate it to using your TAPI controls since they copied many of their features from the TeleTools controls. In general, you would have to have multiple lines exposed via the TSP for the device by what is called a "third party" TSP instead of just a "first party" TSP(otherwise, you will have control over just one line on each computer (but possibly more than one call per line for things like transfer and conference).

For example, a Dialogic 4 port card would give you 4 analog lines. A T1 card would give you access to 24. A PBX would either expose the lines to you through their TSP (telephony service provider driver software), or a SIP trunk for which you would then need the SIP Communication server software from the company above to connect to it. Using SIP DOES model more of the phone side of things, but is an option for people who have hardware with limited TAPI support or where a SIP install is just easier or eliminates licensing issues on PBXs that charge extra for some features.

For example, a Cisco PBX with Call Manager installed can expose multiple lines to TAPI applications. Same goes for Avaya and it's IP Office software. You would not need to thread anything. You simply need multiple controls. Each control initializes a line (as shown in the IVR 4 Line example). If you used a utility like TeleScope or Julmar Phone, or even the EXE version of the IVR program above, you will see in a dropdown all of the devices found on your system. So if you saw "Analog Line1" & "Analog Line2", then you would create 2 line controls and point each one to a different line device. Then you could either have multiple event handlers for each line, Line1_OnConnected, Line2_Onconnected, or more efficiently, create your own "OnConnected" event handler and point all the controls to it and use a property like the "tag" property of a control or the sender/object property in an event handler to parse which control on which line fired your event handler. Again, there are examples for a few development environments on that IVR sample page.

You can use one of the utilities mentioned above to query the "device capabilities" reported by the device. It will tell you the number of calls per line it can handle and which TAPI functions it supports such as putting a call on hold, supporting blind transfers, supervised transfers, conferencing, etc. If you don't have more than one call per line, then you obviously can't dial another call. With 2 calls per line, you would either put the first call on hold (referencing its call handle) and then dial the other call, or setup a transfer or conference (which requires 3 calls minimum). In any case, you would not have more than a few calls and would have to manage them with only one active at a time unless you were in a conference. Using one control per line, you can have multiple calls that are completely independent of each other. Hope that gets you further!

FDecker
  • 41
  • 1
  • 10