/// <summary> /// Call (MSRP, Audio, Video, T.38, ...) events /// </summary> /// <param name="e"></param> /// <returns></returns> public override int OnInviteEvent(InviteEvent e) { tsip_invite_event_type_t type = e.getType(); short code = e.getCode(); String phrase = e.getPhrase(); InviteSession session = e.getSession(); switch (type) { case tsip_invite_event_type_t.tsip_i_newcall: if (session != null) /* As we are not the owner, then the session MUST be null */ { LOG.Error("Invalid incoming session"); session.hangup(); // To avoid another callback event return -1; } SipMessage message = e.getSipMessage(); if (message == null) { LOG.Error("Invalid message"); return -1; } twrap_media_type_t sessionType = e.getMediaType(); switch (sessionType) { case twrap_media_type_t.twrap_media_msrp: { if ((session = e.takeMsrpSessionOwnership()) == null) { LOG.Error("Failed to take MSRP session ownership"); return -1; } MyMsrpSession msrpSession = MyMsrpSession.TakeIncomingSession(this.sipService.SipStack, session as MsrpSession, message); if (msrpSession == null) { LOG.Error("Failed to create new session"); session.hangup(); session.Dispose(); return 0; } msrpSession.State = MyInviteSession.InviteState.INCOMING; InviteEventArgs eargs = new InviteEventArgs(msrpSession.Id, InviteEventTypes.INCOMING, phrase); eargs.AddExtra(InviteEventArgs.EXTRA_SESSION, msrpSession); EventHandlerTrigger.TriggerEvent<InviteEventArgs>(this.sipService.onInviteEvent, this.sipService, eargs); break; } case twrap_media_type_t.twrap_media_audio: case twrap_media_type_t.twrap_media_audiovideo: case twrap_media_type_t.twrap_media_video: { if ((session = e.takeCallSessionOwnership()) == null) { LOG.Error("Failed to take audio/video session ownership"); return -1; } MyAVSession avSession = MyAVSession.TakeIncomingSession(this.sipService.SipStack, session as CallSession, sessionType, message); avSession.State = MyInviteSession.InviteState.INCOMING; InviteEventArgs eargs = new InviteEventArgs(avSession.Id, InviteEventTypes.INCOMING, phrase); eargs.AddExtra(InviteEventArgs.EXTRA_SESSION, avSession); EventHandlerTrigger.TriggerEvent<InviteEventArgs>(this.sipService.onInviteEvent, this.sipService, eargs); break; } default: LOG.Error("Invalid media type"); return 0; } break; case tsip_invite_event_type_t.tsip_ao_request: if (code == 180 && session != null) { EventHandlerTrigger.TriggerEvent<InviteEventArgs>(this.sipService.onInviteEvent, this.sipService, new InviteEventArgs(session.getId(), InviteEventTypes.RINGING, phrase)); } break; case tsip_invite_event_type_t.tsip_i_request: case tsip_invite_event_type_t.tsip_o_ect_ok: case tsip_invite_event_type_t.tsip_o_ect_nok: case tsip_invite_event_type_t.tsip_i_ect: { break; } case tsip_invite_event_type_t.tsip_m_early_media: { EventHandlerTrigger.TriggerEvent<InviteEventArgs>(this.sipService.onInviteEvent, this.sipService, new InviteEventArgs(session.getId(), InviteEventTypes.EARLY_MEDIA, phrase)); break; } case tsip_invite_event_type_t.tsip_m_local_hold_ok: { EventHandlerTrigger.TriggerEvent<InviteEventArgs>(this.sipService.onInviteEvent, this.sipService, new InviteEventArgs(session.getId(), InviteEventTypes.LOCAL_HOLD_OK, phrase)); break; } case tsip_invite_event_type_t.tsip_m_local_hold_nok: { EventHandlerTrigger.TriggerEvent<InviteEventArgs>(this.sipService.onInviteEvent, this.sipService, new InviteEventArgs(session.getId(), InviteEventTypes.LOCAL_HOLD_NOK, phrase)); break; } case tsip_invite_event_type_t.tsip_m_local_resume_ok: { EventHandlerTrigger.TriggerEvent<InviteEventArgs>(this.sipService.onInviteEvent, this.sipService, new InviteEventArgs(session.getId(), InviteEventTypes.LOCAL_RESUME_OK, phrase)); break; } case tsip_invite_event_type_t.tsip_m_local_resume_nok: { EventHandlerTrigger.TriggerEvent<InviteEventArgs>(this.sipService.onInviteEvent, this.sipService, new InviteEventArgs(session.getId(), InviteEventTypes.LOCAL_RESUME_NOK, phrase)); break; } case tsip_invite_event_type_t.tsip_m_remote_hold: { EventHandlerTrigger.TriggerEvent<InviteEventArgs>(this.sipService.onInviteEvent, this.sipService, new InviteEventArgs(session.getId(), InviteEventTypes.REMOTE_HOLD, phrase)); break; } case tsip_invite_event_type_t.tsip_m_remote_resume: { EventHandlerTrigger.TriggerEvent<InviteEventArgs>(this.sipService.onInviteEvent, this.sipService, new InviteEventArgs(session.getId(), InviteEventTypes.REMOTE_RESUME, phrase)); break; } } return 0; }
/// <summary> /// Dialog events (Common to all) /// </summary> /// <param name="e"></param> /// <returns></returns> public override int OnDialogEvent(DialogEvent e) { String phrase = e.getPhrase(); short code = e.getCode(); SipSession session = e.getBaseSession(); if (session == null) { return 0; } uint sessionId = session.getId(); MySipSession mySession = null; SipService.LOG.Info(String.Format("OnDialogEvent ({0})", phrase)); if (code == tinyWRAP.tsip_event_code_dialog_connecting) { // Registration if (this.sipService.regSession != null && this.sipService.regSession.Id == sessionId) { EventHandlerTrigger.TriggerEvent<RegistrationEventArgs>(this.sipService.onRegistrationEvent, this.sipService, new RegistrationEventArgs(RegistrationEventTypes.REGISTRATION_INPROGRESS, code, phrase)); } // Audio/Video/MSRP else if (((mySession = MyAVSession.GetSession(sessionId)) != null) || ((mySession = MyMsrpSession.GetSession(sessionId)) != null)) { (mySession as MyInviteSession).State = MyInviteSession.InviteState.INPROGRESS; InviteEventArgs eargs = new InviteEventArgs(sessionId, InviteEventTypes.INPROGRESS, phrase); eargs.AddExtra(InviteEventArgs.EXTRA_SESSION, mySession); EventHandlerTrigger.TriggerEvent<InviteEventArgs>(this.sipService.onInviteEvent, this.sipService, eargs); } // Subscription // Publication } else if (code == tinyWRAP.tsip_event_code_dialog_connected) { // Registration if (this.sipService.regSession != null && this.sipService.regSession.Id == sessionId) { this.sipService.regSession.IsConnected = true; // Update default identity (vs barred) String _defaultIdentity = this.sipService.SipStack.getPreferredIdentity(); if (!String.IsNullOrEmpty(_defaultIdentity)) { this.sipService.defaultIdentity = _defaultIdentity; } // Do PostRegistrationOp() in new thread to avoid blocking callbacks new Thread(new ThreadStart(delegate { this.sipService.DoPostRegistrationOp(); })) .Start(); EventHandlerTrigger.TriggerEvent<RegistrationEventArgs>(this.sipService.onRegistrationEvent, this.sipService, new RegistrationEventArgs(RegistrationEventTypes.REGISTRATION_OK, code, phrase)); } // Audio/Video/MSRP else if (((mySession = MyAVSession.GetSession(sessionId)) != null) || ((mySession = MyMsrpSession.GetSession(sessionId)) != null)) { (mySession as MyInviteSession).State = MyInviteSession.InviteState.INCALL; mySession.IsConnected = true; EventHandlerTrigger.TriggerEvent<InviteEventArgs>(this.sipService.onInviteEvent, this.sipService, new InviteEventArgs(sessionId, InviteEventTypes.CONNECTED, phrase)); } // Subscription else if ((mySession = this.sipService.subPresence.FirstOrDefault(x => x.Id == sessionId)) != null) { mySession.IsConnected = true; } // Publication else if (this.sipService.pubPres != null && this.sipService.pubPres.Id == sessionId) { this.sipService.pubPres.IsConnected = true; } } else if (code == tinyWRAP.tsip_event_code_dialog_terminating) { // Registration if (this.sipService.regSession != null && this.sipService.regSession.Id == sessionId) { EventHandlerTrigger.TriggerEvent<RegistrationEventArgs>(this.sipService.onRegistrationEvent, this.sipService, new RegistrationEventArgs(RegistrationEventTypes.UNREGISTRATION_INPROGRESS, code, phrase)); } // Audio/Video/MSRP else if (((mySession = MyAVSession.GetSession(sessionId)) != null) || ((mySession = MyMsrpSession.GetSession(sessionId)) != null)) { (mySession as MyInviteSession).State = MyInviteSession.InviteState.TERMINATING; EventHandlerTrigger.TriggerEvent<InviteEventArgs>(this.sipService.onInviteEvent, this.sipService, new InviteEventArgs(sessionId, InviteEventTypes.TERMWAIT, phrase)); } // Subscription // Publication } else if (code == tinyWRAP.tsip_event_code_dialog_terminated) { // Registration if (this.sipService.regSession != null && this.sipService.regSession.Id == sessionId) { this.sipService.regSession.IsConnected = false; // To PostRegistration() in new thread EventHandlerTrigger.TriggerEvent<RegistrationEventArgs>(this.sipService.onRegistrationEvent, this.sipService, new RegistrationEventArgs(RegistrationEventTypes.UNREGISTRATION_OK, code, phrase)); /* Stop the stack (as we are already in the stack-thread, then do it in a new thread) */ new Thread(new ThreadStart(delegate { if (this.sipService.sipStack.State == MySipStack.STACK_STATE.STARTED) { this.sipService.sipStack.stop(); } })).Start(); } // Audio/Video/MSRP else if (((mySession = MyAVSession.GetSession(sessionId)) != null) || ((mySession = MyMsrpSession.GetSession(sessionId)) != null)) { mySession.IsConnected = false; (mySession as MyInviteSession).State = MyInviteSession.InviteState.TERMINATED; EventHandlerTrigger.TriggerEvent<InviteEventArgs>(this.sipService.onInviteEvent, this.sipService, new InviteEventArgs(sessionId, InviteEventTypes.DISCONNECTED, phrase)); } // Subscription else if ((mySession = this.sipService.subPresence.FirstOrDefault(x => x.Id == sessionId)) != null) { mySession.IsConnected = false; this.sipService.subPresence.Remove(mySession as MySubscriptionSession); } // Publication else if (this.sipService.pubPres != null && this.sipService.pubPres.Id == sessionId) { this.sipService.pubPres.IsConnected = false; if (this.sipService.hyperAvailabilityTimer != null) { if (this.sipService.hyperAvailabilityTimer.Enabled) { this.sipService.hyperAvailabilityTimer.Stop(); } this.sipService.hyperAvailabilityTimer = null; } } } return 0; }
/// <summary> /// Call (MSRP, Audio, Video, T.38, ...) events /// </summary> /// <param name="e"></param> /// <returns></returns> public override int OnInviteEvent(InviteEvent e) { tsip_invite_event_type_t type = e.getType(); short code = e.getCode(); String phrase = e.getPhrase(); InviteSession session = e.getSession(); switch (type) { case tsip_invite_event_type_t.tsip_i_newcall: case tsip_invite_event_type_t.tsip_i_ect_newcall: { if (session != null) /* As we are not the owner, then the session MUST be null */ { LOG.Error("Invalid incoming session"); session.hangup(null); // To avoid another callback event return -1; } SipMessage message = e.getSipMessage(); if (message == null) { LOG.Error("Invalid message"); return -1; } twrap_media_type_t sessionType = e.getMediaType(); switch (sessionType) { case twrap_media_type_t.twrap_media_msrp: { if ((session = e.takeMsrpSessionOwnership()) == null) { LOG.Error("Failed to take MSRP session ownership"); return -1; } MyMsrpSession msrpSession = MyMsrpSession.TakeIncomingSession(this.sipService.SipStack, session as MsrpSession, message); if (msrpSession == null) { LOG.Error("Failed to create new session"); session.hangup(null); (session as IDisposable).Dispose(); return 0; } msrpSession.State = MyInviteSession.InviteState.INCOMING; InviteEventArgs eargs = new InviteEventArgs(msrpSession.Id, InviteEventTypes.INCOMING, phrase); eargs.AddExtra(InviteEventArgs.EXTRA_SESSION, msrpSession); EventHandlerTrigger.TriggerEvent<InviteEventArgs>(this.sipService.onInviteEvent, this.sipService, eargs); break; } case twrap_media_type_t.twrap_media_audio: case twrap_media_type_t.twrap_media_audiovideo: case twrap_media_type_t.twrap_media_video: case (twrap_media_type_t.twrap_media_audio | twrap_media_type_t.twrap_media_t140): case (twrap_media_type_t.twrap_media_audio | twrap_media_type_t.twrap_media_video | twrap_media_type_t.twrap_media_t140): case twrap_media_type_t.twrap_media_t140: { if ((session = e.takeCallSessionOwnership()) == null) { LOG.Error("Failed to take audio/video session ownership"); return -1; } if (type == tsip_invite_event_type_t.tsip_i_newcall) { MyAVSession avSession = MyAVSession.TakeIncomingSession(this.sipService.SipStack, session as CallSession, sessionType, message); avSession.State = MyInviteSession.InviteState.INCOMING; InviteEventArgs eargs = new InviteEventArgs(avSession.Id, InviteEventTypes.INCOMING, phrase); eargs.AddExtra(InviteEventArgs.EXTRA_SESSION, avSession); EventHandlerTrigger.TriggerEvent<InviteEventArgs>(this.sipService.onInviteEvent, this.sipService, eargs); } else { MyAVSession avSession = MyAVSession.TakeOutgoingTranferSession(this.sipService.SipStack, (session as CallSession), sessionType, message); InviteEventArgs eargs = new InviteEventArgs(avSession.Id, InviteEventTypes.REMOTE_TRANSFER_INPROGESS, phrase); eargs.AddExtra(InviteEventArgs.EXTRA_SESSION, avSession); EventHandlerTrigger.TriggerEvent<InviteEventArgs>(this.sipService.onInviteEvent, this.sipService, eargs); } break; } default: LOG.Error("Invalid media type"); return 0; } break; } case tsip_invite_event_type_t.tsip_ao_request: if (code == 180 && session != null) { EventHandlerTrigger.TriggerEvent<InviteEventArgs>(this.sipService.onInviteEvent, this.sipService, new InviteEventArgs(session.getId(), InviteEventTypes.RINGING, phrase)); } break; case tsip_invite_event_type_t.tsip_i_request: { SipMessage message = e.getSipMessage(); if (message != null) { if (message.getRequestType() == tsip_request_type_t.tsip_INFO) { String from = message.getSipHeaderValue("f"); String contentType = message.getSipHeaderValue("c"); //byte[] bytes = message.getSipContent(); //if (!String.IsNullOrEmpty(contentType) && String.Equals(contentType, ContentType.DOUBANGO_DEVICE_INFO, StringComparison.InvariantCultureIgnoreCase)) //{ // if (bytes != null) // { // //InviteEventArgs eargs = new InviteEventArgs(session.getId(), InviteEventTypes.INFO, e.getPhrase()); // // eargs // // .AddExtra(InviteEventArgs.EXTRA_CONTENT, from) // // .AddExtra(InviteEventArgs.EXTRA_REMOTE_PARTY, from) // // .AddExtra(InviteEventArgs.EXTRA_CONTENT_TYPE, contentType == null ? ContentType.UNKNOWN : contentType); // // EventHandlerTrigger.TriggerEvent<InviteEventArgs>(this.sipService.onInviteEvent, this.sipService, eargs); // } // } } } break; } case tsip_invite_event_type_t.tsip_o_ect_trying: { EventHandlerTrigger.TriggerEvent<InviteEventArgs>(this.sipService.onInviteEvent, this.sipService, new InviteEventArgs(session.getId(), InviteEventTypes.LOCAL_TRANSFER_TRYING, phrase)); break; } case tsip_invite_event_type_t.tsip_o_ect_accepted: { EventHandlerTrigger.TriggerEvent<InviteEventArgs>(this.sipService.onInviteEvent, this.sipService, new InviteEventArgs(session.getId(), InviteEventTypes.LOCAL_TRANSFER_ACCEPTED, phrase)); break; } case tsip_invite_event_type_t.tsip_o_ect_completed: { EventHandlerTrigger.TriggerEvent<InviteEventArgs>(this.sipService.onInviteEvent, this.sipService, new InviteEventArgs(session.getId(), InviteEventTypes.LOCAL_TRANSFER_COMPLETED, phrase)); break; } case tsip_invite_event_type_t.tsip_o_ect_failed: { EventHandlerTrigger.TriggerEvent<InviteEventArgs>(this.sipService.onInviteEvent, this.sipService, new InviteEventArgs(session.getId(), InviteEventTypes.LOCAL_TRANSFER_FAILED, phrase)); break; } case tsip_invite_event_type_t.tsip_o_ect_notify: case tsip_invite_event_type_t.tsip_i_ect_notify: { InviteEventTypes eType = type == tsip_invite_event_type_t.tsip_o_ect_notify ? InviteEventTypes.LOCAL_TRANSFER_NOTIFY : InviteEventTypes.REMOTE_TRANSFER_NOTIFY; InviteEventArgs args = new InviteEventArgs(session.getId(), eType, phrase); args.AddExtra(InviteEventArgs.EXTRA_SIP_CODE, code); EventHandlerTrigger.TriggerEvent<InviteEventArgs>(this.sipService.onInviteEvent, this.sipService, args); break; } case tsip_invite_event_type_t.tsip_i_ect_requested: { SipMessage message = e.getSipMessage(); if (message != null) { if (message.getRequestType() == tsip_request_type_t.tsip_REFER) { String referToUri = message.getSipHeaderValue("refer-to"); if (!String.IsNullOrEmpty(referToUri)) { InviteEventArgs args = new InviteEventArgs(session.getId(), InviteEventTypes.REMOTE_TRANSFER_REQUESTED, phrase); args.AddExtra(InviteEventArgs.EXTRA_REFERTO_URI, referToUri); EventHandlerTrigger.TriggerEvent<InviteEventArgs>(this.sipService.onInviteEvent, this.sipService, args); } } } break; } case tsip_invite_event_type_t.tsip_i_ect_failed: { EventHandlerTrigger.TriggerEvent<InviteEventArgs>(this.sipService.onInviteEvent, this.sipService, new InviteEventArgs(session.getId(), InviteEventTypes.REMOTE_TRANSFER_FAILED, phrase)); break; } case tsip_invite_event_type_t.tsip_i_ect_completed: { EventHandlerTrigger.TriggerEvent<InviteEventArgs>(this.sipService.onInviteEvent, this.sipService, new InviteEventArgs(session.getId(), InviteEventTypes.REMOTE_TRANSFER_COMPLETED, phrase)); break; } case tsip_invite_event_type_t.tsip_m_early_media: { EventHandlerTrigger.TriggerEvent<InviteEventArgs>(this.sipService.onInviteEvent, this.sipService, new InviteEventArgs(session.getId(), InviteEventTypes.EARLY_MEDIA, phrase)); break; } case tsip_invite_event_type_t.tsip_m_updating: { EventHandlerTrigger.TriggerEvent<InviteEventArgs>(this.sipService.onInviteEvent, this.sipService, new InviteEventArgs(session.getId(), InviteEventTypes.MEDIA_UPDATING, phrase)); break; } case tsip_invite_event_type_t.tsip_m_updated: { if (MyAVSession.HandleMediaUpdate(session.getId(), e.getMediaType())) { EventHandlerTrigger.TriggerEvent<InviteEventArgs>(this.sipService.onInviteEvent, this.sipService, new InviteEventArgs(session.getId(), InviteEventTypes.MEDIA_UPDATED, phrase)); } break; } case tsip_invite_event_type_t.tsip_m_local_hold_ok: { EventHandlerTrigger.TriggerEvent<InviteEventArgs>(this.sipService.onInviteEvent, this.sipService, new InviteEventArgs(session.getId(), InviteEventTypes.LOCAL_HOLD_OK, phrase)); break; } case tsip_invite_event_type_t.tsip_m_local_hold_nok: { EventHandlerTrigger.TriggerEvent<InviteEventArgs>(this.sipService.onInviteEvent, this.sipService, new InviteEventArgs(session.getId(), InviteEventTypes.LOCAL_HOLD_NOK, phrase)); break; } case tsip_invite_event_type_t.tsip_m_local_resume_ok: { EventHandlerTrigger.TriggerEvent<InviteEventArgs>(this.sipService.onInviteEvent, this.sipService, new InviteEventArgs(session.getId(), InviteEventTypes.LOCAL_RESUME_OK, phrase)); break; } case tsip_invite_event_type_t.tsip_m_local_resume_nok: { EventHandlerTrigger.TriggerEvent<InviteEventArgs>(this.sipService.onInviteEvent, this.sipService, new InviteEventArgs(session.getId(), InviteEventTypes.LOCAL_RESUME_NOK, phrase)); break; } case tsip_invite_event_type_t.tsip_m_remote_hold: { EventHandlerTrigger.TriggerEvent<InviteEventArgs>(this.sipService.onInviteEvent, this.sipService, new InviteEventArgs(session.getId(), InviteEventTypes.REMOTE_HOLD, phrase)); break; } case tsip_invite_event_type_t.tsip_m_remote_resume: { EventHandlerTrigger.TriggerEvent<InviteEventArgs>(this.sipService.onInviteEvent, this.sipService, new InviteEventArgs(session.getId(), InviteEventTypes.REMOTE_RESUME, phrase)); break; } } return 0; }