Example #1
0
        /// <summary>
        /// Processes the TAPI messages
        /// </summary>
        private void ProcessTapiMessages()
        {
            var arrWait = new WaitHandle[] { _evtStop, _evtReceivedLineEvent, _evtReceivedPhoneEvent };
            var msg     = new LINEMESSAGE();
            ProcessTapiMessageDelegate ptmCb = ProcessTapiMessage;

            int rc = 0;

            bool stopEventRaised = false;

            while (!stopEventRaised)
            {
                try
                {
                    switch (WaitHandle.WaitAny(arrWait))
                    {
                    case 0:
                        stopEventRaised = true;
                        break;

                    case 1:
                        rc = NativeMethods.lineGetMessage(_hTapiLine, ref msg, 0);
                        break;

                    case 2:
                        rc = NativeMethods.phoneGetMessage(_hTapiPhone, ref msg, 0);
                        break;
                    }
                }



                // Someone called Shutdown with pending requests..
                catch (ObjectDisposedException)
                {
                    break;
                }

                if (rc == NativeMethods.LINEERR_OK)
                {
                    // Call on another worker thread - just in case the UI
                    // made a blocking call and is waiting on the result from this
                    // thread.. if the WinForms/WPF app then attempts to marshal to
                    // the UI thread from this callback it will deadlock.
                    ptmCb.BeginInvoke(msg, ar =>
                    {
                        try
                        {
                            ptmCb.EndInvoke(ar);
                        }
                        catch (Exception ex)
                        {
                            Trace.WriteLine("TAPI message exception: " + ex.Message);
                        }
                    }, null);
                }
            }
        }
Example #2
0
        private void ProcessTapiMessage(LINEMESSAGE msg)
        {
            switch (msg.dwMessageID)
            {
            case TapiEvent.LINE_CALLSTATE:
            {
                TapiCall call = TapiCall.FindCallByHandle(msg.hDevice);
                if (call != null)
                {
                    call.OnCallStateChange(msg.dwParam1.ToInt32(), msg.dwParam2, (MediaModes)msg.dwParam3.ToInt32());
                }
                else
                {
                    // Call doesn't exist (yet), wait for a LINE_REPLY to add the call.
                    lock (_pendingCallStateMessages)
                    {
                        _pendingCallStateMessages.Add(Tuple.Create(DateTime.Now, msg));
                    }
                }
            }
            break;

            case TapiEvent.LINE_CALLINFO:
            {
                TapiCall call = TapiCall.FindCallByHandle(msg.hDevice);
                if (call != null)
                {
                    call.OnCallInfoChange(msg.dwParam1.ToInt32());
                }
            }
            break;

            case TapiEvent.LINE_GATHERDIGITS:
            {
                TapiCall call = TapiCall.FindCallByHandle(msg.hDevice);
                if (call != null)
                {
                    call.OnGatherDigitsComplete(msg.dwParam1.ToInt32());
                }
            }
            break;

            case TapiEvent.LINE_GENERATE:
            {
                TapiCall call = TapiCall.FindCallByHandle(msg.hDevice);
                if (call != null)
                {
                    call.OnGenerateDigitsOrToneComplete(msg.dwParam1.ToInt32());
                }
            }
            break;

            case TapiEvent.LINE_MONITORDIGITS:
            {
                TapiCall call = TapiCall.FindCallByHandle(msg.hDevice);
                if (call != null)
                {
                    call.OnDigitDetected(msg.dwParam1.ToInt32(), msg.dwParam2.ToInt32());
                }
            }
            break;

            case TapiEvent.LINE_MONITORMEDIA:
            {
                TapiCall call = TapiCall.FindCallByHandle(msg.hDevice);
                if (call != null)
                {
                    call.OnMediaModeDetected((MediaModes)msg.dwParam1.ToInt32());
                }
            }
            break;

            case TapiEvent.LINE_MONITORTONE:
            {
                TapiCall call = TapiCall.FindCallByHandle(msg.hDevice);
                if (call != null)
                {
                    call.OnToneDetected(msg.dwParam1.ToInt32());
                }
            }
            break;

            case TapiEvent.LINE_LINEDEVSTATE:
                if (msg.dwParam1.ToInt32() == NativeMethods.LINEDEVSTATE_REINIT && msg.dwParam2.ToInt32() == 0)
                {
                    if (ReinitRequired != null)
                    {
                        ReinitRequired(this, EventArgs.Empty);
                    }
                }
                goto case TapiEvent.LINE_CLOSE;

            case TapiEvent.LINE_DEVSPECIFIC:
            {
                TapiCall call = TapiCall.FindCallByHandle(msg.hDevice);
                if (call != null)
                {
                    ((TapiLine)call.Line).OnDeviceSpecific(call, msg.dwParam1, msg.dwParam2, msg.dwParam3);
                }
                else
                {
                    goto case TapiEvent.LINE_CLOSE;
                }
            }
            break;

            case TapiEvent.LINE_DEVSPECIFICFEATURE:
            {
                TapiLine line = null;
                lock (_lineArray)
                {
                    foreach (TapiLine currLine in _lineArray)
                    {
                        if (currLine.Handle.DangerousGetHandle() == (IntPtr)msg.hDevice)
                        {
                            line = currLine;
                            break;
                        }
                    }
                }
                if (line != null)
                {
                    line.OnDeviceSpecific(null, msg.dwParam1, msg.dwParam2, msg.dwParam3);
                }
            }
            break;

            case TapiEvent.LINE_AGENTSTATUS:
            case TapiEvent.LINE_AGENTSTATUSEX:
            case TapiEvent.LINE_AGENTSPECIFIC:
            case TapiEvent.LINE_AGENTSESSIONSTATUS:
            case TapiEvent.LINE_PROXYREQUEST:
            case TapiEvent.LINE_PROXYSTATUS:
            case TapiEvent.LINE_QUEUESTATUS:
            case TapiEvent.LINE_REQUEST:
                break;

            case TapiEvent.PHONE_BUTTON:
            case TapiEvent.PHONE_CLOSE:
            case TapiEvent.PHONE_DEVSPECIFIC:

            case TapiEvent.PHONE_REPLY:
                HandleCompletion(msg.dwParam1.ToInt32(), msg.dwParam2);
                break;

            case TapiEvent.PHONE_STATE:
                break;

            case TapiEvent.PHONE_CREATE:
            {
                var newPhone = new TapiPhone(this, msg.dwParam1.ToInt32());
                lock (_phoneArray)
                {
                    _phoneArray.Add(newPhone);
                }
                if (PhoneAdded != null)
                {
                    PhoneAdded(this, new PhoneAddedEventArgs(newPhone));
                }
            }
            break;

            case TapiEvent.PHONE_REMOVE:
            {
                TapiPhone phone = null;
                lock (_phoneArray)
                {
                    if (msg.dwParam1.ToInt32() < _phoneArray.Count)
                    {
                        phone = _phoneArray[msg.dwParam1.ToInt32()];
                    }
                }
                if (phone != null)
                {
                    phone.IsValid = false;
                    if (PhoneRemoved != null)
                    {
                        PhoneRemoved(this, new PhoneRemovedEventArgs(phone));
                    }
                }
            }
            break;

            case TapiEvent.LINE_ADDRESSSTATE:
            case TapiEvent.LINE_CLOSE:
            case TapiEvent.LINE_APPNEWCALL:
                if (msg.dwCallbackInstance != IntPtr.Zero)
                {
                    try
                    {
                        var callback = (TapiEventCallback)Marshal.GetDelegateForFunctionPointer(msg.dwCallbackInstance, typeof(TapiEventCallback));
                        callback.Invoke(msg.dwMessageID, msg.dwParam1, msg.dwParam2, msg.dwParam3);
                    }
                    catch (Exception ex)
                    {
                        Trace.WriteLine(ex);
                    }
                }
                break;

            case TapiEvent.LINE_CREATE:
            {
                var newLine = new TapiLine(this, msg.dwParam1.ToInt32());

                // Add event handlers
                newLine.NewCall          += HandleNewCall;
                newLine.CallStateChanged += HandleCallStateChanged;
                newLine.CallInfoChanged  += HandleCallInfoChanged;
                newLine.AddressChanged   += HandleAddressChanged;
                newLine.Changed          += HandleLineChanged;
                newLine.Ringing          += HandleLineRinging;

                lock (_lineArray)
                {
                    _lineArray.Add(newLine);
                }
                if (LineAdded != null)
                {
                    LineAdded(this, new LineAddedEventArgs(newLine));
                }
            }
            break;

            case TapiEvent.LINE_REMOVE:
            {
                TapiLine line = null;
                lock (_lineArray)
                {
                    if (msg.dwParam1.ToInt32() < _lineArray.Count)
                    {
                        line = _lineArray[msg.dwParam1.ToInt32()];
                    }
                }
                if (line != null)
                {
                    line.IsValid = false;
                    if (LineRemoved != null)
                    {
                        LineRemoved(this, new LineRemovedEventArgs(line));
                    }
                }
            }
            break;

            case TapiEvent.LINE_REPLY:
                HandleCompletion(msg.dwParam1.ToInt32(), msg.dwParam2);
                break;


            default:
                break;
            }
        }