1

I'm writing TAPI 3.0 app in C# for land line telephone. My goal is to receive and record calls. So far in my Code Everything works fine for the first call, all events are triggering.

But unfortunately, all subsequent calls are completely ignored by TAPI after first call and

no event is triggering until I restart the app again.

One thing I had found while googling if I reset Tapi instance it can solve my problem,

Can anyone tell how to reset Tapi object?

Here is my code

void initializetapi3()
{
    try
    {
        tobj = new TAPIClass();
        tobj.Initialize();
        IEnumAddress ea=tobj.EnumerateAddresses();
        ITAddress ln;
        uint arg3=0;
        lines=0;

        cn=new callnotification();
        cn.addtolist=new callnotification.listshow(this.status);
        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|TAPI_EVENT.TE_CALLINFOCHANGE);


        for(int i=0;i<10;i++)
        {
            ea.Next(1,out ln,ref arg3);
            ia[i]=ln;
            if(ln!=null)
            {
                comboBox1.Items.Add(ia[i].AddressName);
                lines++;
            }
            else
                break;
        }


    }
    catch(Exception e)
    {
        MessageBox.Show(e.ToString());
    }
}

delegate void valueDelegate(string value);

public void status(string str)
{
    if (textBox1.InvokeRequired)
    {
        textBox1.Invoke(new valueDelegate(status), str);
    }
    else
    {
        textBox1.Text = str;
    } 
}

public void Event(TAPI3Lib.TAPI_EVENT te, object eobj)
{
    switch (te)
    {
        case TAPI3Lib.TAPI_EVENT.TE_CALLNOTIFICATION:
            status("call notification event has occured");
            break;
        case TAPI3Lib.TAPI_EVENT.TE_PHONEEVENT:
            status("A phone event!");
            break;
        case TAPI3Lib.TAPI_EVENT.TE_CALLSTATE:
            TAPI3Lib.ITCallStateEvent a = (TAPI3Lib.ITCallStateEvent)eobj;
            TAPI3Lib.ITCallInfo b = a.Call;
            switch (b.CallState)
            {
                case TAPI3Lib.CALL_STATE.CS_INPROGRESS:

                   status("dialing");
                    break;
                case TAPI3Lib.CALL_STATE.CS_CONNECTED:
                     status("Connected");
                    break;
                case TAPI3Lib.CALL_STATE.CS_DISCONNECTED:
                    status("Disconnected");
                    break;
                case TAPI3Lib.CALL_STATE.CS_OFFERING:
                    status("A party wants to communicate with you!");
                    break;
                case TAPI3Lib.CALL_STATE.CS_IDLE:
                    status("Call is created!");
                    break;
            }
            break;
    }
}
Naveed Yousaf
  • 436
  • 4
  • 14
  • I want to avoid the first solution below if I can, and the second solutions below did not work for me. Did you find a solution yourself? – Rob Jul 31 '15 at 18:18
  • never mind, I found the solution, see answer below – Rob Aug 01 '15 at 02:10

4 Answers4

1

Have you tried calling:

tobj.Shutdown();
initializetapi3();

after receiving TAPI3Lib.CALL_STATE.CS_DISCONNECTED event (or after any event)? So, for example:

case TAPI3Lib.CALL_STATE.CS_DISCONNECTED:
    status("Disconnected");
    tobj.Shutdown();
    initializetapi3();
    break;
kapibarra
  • 11
  • 1
1

This will work fine for you....:

Private void initializetapi()
{
    try
    {
        tobj = new TAPIClass();
        tobj.Initialize();
        IEnumAddress ea=tobj.EnumerateAddresses();
        ITAddress ln;
        uint arg3=0;
        lines=0;
        cn=new callnotification();
        cn.addtolist=new callnotification.listshow(this.status);
        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|TAPI_EVENT.TE_CALLINFOCHANGE);


        for(int i=0;i<10;i++)
        {
            ea.Next(1,out ln,ref arg3);
            ia[i]=ln;
            if(ln!=null)
            {
                comboBox1.Items.Add(ia[i].AddressName);
                lines++;
            }
            else
                break;
        }


    }
    catch(Exception e)
    {
        MessageBox.Show(e.ToString());
    }
}

delegate void valueDelegate(string value);

public void status(string str)
{
    if (textBox1.InvokeRequired)
    {
        textBox1.Invoke(new valueDelegate(status), str);
    }
    else
    {
        textBox1.Text = str;
    } 
}

public void Event(TAPI3Lib.TAPI_EVENT te, object eobj)
{
    switch (te)
    {
        case TAPI3Lib.TAPI_EVENT.TE_CALLNOTIFICATION:
        var cn = te as TAPI3Lib.ITCallNotificationEvent;
        int counter = 0;
        while (cn.Call.CallState == TAPI3Lib.CALL_STATE.CS_IDLE && counter++ < 2)
        {
            System.Threading.Thread.Sleep(1000);
        }
            status("call notification event has occured");
            break;
        case TAPI3Lib.TAPI_EVENT.TE_PHONEEVENT:
            status("A phone event!");
            break;
        case TAPI3Lib.TAPI_EVENT.TE_CALLSTATE:
            TAPI3Lib.ITCallStateEvent a = (TAPI3Lib.ITCallStateEvent)eobj;
            TAPI3Lib.ITCallInfo b = a.Call;
            switch (b.CallState)
            {
                case TAPI3Lib.CALL_STATE.CS_INPROGRESS:

                   status("dialing");
                    break;
                case TAPI3Lib.CALL_STATE.CS_CONNECTED:
                     status("Connected");
                    break;
                case TAPI3Lib.CALL_STATE.CS_DISCONNECTED:
                    status("Disconnected");
                    break;
                case TAPI3Lib.CALL_STATE.CS_OFFERING:
                    status("A party wants to communicate with you!");
                    break;
                case TAPI3Lib.CALL_STATE.CS_IDLE:
                    status("Call is created!");
                    break;
            }
            break;
    }
}

and that's because in first call your call state is Idle for less than milliseconds.

Mahdi Shahbazi
  • 1,063
  • 1
  • 10
  • 13
1

The solution is wait until the tapi callstate disconnect event, and once this has happened:

a) UnRegisterDeviceForEvents the device address associated with the disconnect event, and then

b) RegisterCallNotifications the device address associated with the disconnect event

Rob
  • 3,488
  • 3
  • 32
  • 27
0

For this problem I used a managed C# wrapper for Tapi written by Julmar , that can be downloaded, By using this Sample incoming calls could also be recroded in .wav format

    TPhone tphone;
    TTapi tobj;
    TTerminal recordTerminal;
    TCall CurrCall;


    void InitializeTapi()
    {
        tobj = new TTapi();
        tobj.Initialize();

        tobj.TE_CALLNOTIFICATION += new System.EventHandler<JulMar.Tapi3.TapiCallNotificationEventArgs>(this.OnNewCall);
        tobj.TE_CALLSTATE += new System.EventHandler<JulMar.Tapi3.TapiCallStateEventArgs>(this.OnCallState);       
        tobj.TE_CALLINFOCHANGE += tobj_TE_CALLINFOCHANGE;


        foreach (TPhone tp in tobj.Phones)
        {
            tphone = tp;
            tphone.Open(PHONE_PRIVILEGE.PP_OWNER);

        }


        foreach (TAddress addr in tobj.Addresses)
        {
            if (addr.QueryMediaType(TAPIMEDIATYPES.AUDIO))
            {
                try
                {
                    addr.Open(TAPIMEDIATYPES.AUDIO);
                }
                catch (TapiException ex)
                {
                    if (ex.ErrorCode == unchecked((int)0x80040004))
                    {
                        try
                        {
                            addr.Open(TAPIMEDIATYPES.DATAMODEM);

                        }
                        catch (Exception ex2)
                        {
                        }
                    }
                }
            }
        }
    }




    void tobj_TE_CALLINFOCHANGE(object sender, TapiCallInfoChangeEventArgs e)
    {
        try
        {

            CurrCall = e.Call;
            txtCallerId.Text = e.Call.get_CallInfo(CALLINFO_STRING.CIS_CALLERIDNUMBER).ToString();
            objCallLog.CallerID = txtCallerId.Text;

            Task.Factory.StartNew(() => AnswerCall());               


        }
        catch (Exception ex)
        {

        }
    }

    void OnNewCall(object sender, TapiCallNotificationEventArgs e)
    {
        CurrCall = e.Call;
    }

    void OnCallState(object sender, EventArgs E)
    {
        try
        {
            TapiCallStateEventArgs e = E as TapiCallStateEventArgs;
            CurrCall = e.Call;


            TapiPhoneEventArgs ev = E as TapiPhoneEventArgs;

            switch (e.State)
            {

                case CALL_STATE.CS_OFFERING:

                    break;

                case CALL_STATE.CS_CONNECTED:


                    break;

                case CALL_STATE.CS_DISCONNECTED:

                    try
                    {
                        if (recordTerminal != null)
                            recordTerminal.Stop();
                        recordTerminal = null;

                        CurrCall.Dispose();

                    }
                    catch (Exception ex)
                    {
                    }
                    finally
                    {
                        CurrCall = null;
                    }



                    break;
            }


        }
        catch (Exception ex)
        {

        }
    }

    void OnCallChangeEvent(object sender, TapiCallInfoChangeEventArgs e)
    {
        CurrCall = e.Call;
    }



private void AnswerCall()
    {
        try
        {
            lock (lockAnswer)
            {
                if (CallStat == CallState.Offering)
                {
                    CurrCall.Answer();
                    RecordConversation();
                }
                else
                {
                }
            }
        }
        catch (Exception ex)
        {
        }
    }

     void RecordConversation()
    {


        if (CurrCall != null)
        {
            try
            {
                recordTerminal = CurrCall.RequestTerminal(
                TTerminal.FileRecordingTerminal,
                TAPIMEDIATYPES.MULTITRACK, TERMINAL_DIRECTION.TD_RENDER);
                if (recordTerminal != null)
                {
                    recordTerminal.RecordFileName = "FileName.wav";
                    CurrCall.SelectTerminalOnCall(recordTerminal);
                    recordTerminal.Start();
                }
                else
                {
                    MessageBox.Show("Error in recording file.");
                }
            }
            catch (TapiException ex)
            {
                MessageBox.Show(ex.ToString());
            }

        }

    }
Naveed Yousaf
  • 436
  • 4
  • 14