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; } }