/// <summary> /// Notifies the associated SIP application that a dialog has been created. /// </summary> /// <param name="dialog">The dialog.</param> /// <param name="ua">The ua.</param> public void DialogCreated(Dialog dialog, UserAgent ua) { App.DialogCreated(dialog, ua, this); }
/// <summary> /// Handles the received response and passes it to the appropriate transaction or dialog for further handling. /// </summary> /// <param name="r">The received response.</param> /// <param name="uri">The SIP URI.</param> private void ReceivedResponse(Message r, SIPURI uri) { if (r.Headers.ContainsKey("Service-Route") && r.Is2XX() && r.First("CSeq").Method.Contains("REGISTER")) { ServiceRoute = r.Headers["Service-Route"]; foreach (Header h in ServiceRoute) { h.Name = "Route"; } } else if (r.Headers.ContainsKey("Record-Route") && r.Is2XX()) { // TODO: FIX This ? don't need to keep building record-route ? //InviteRecordRoute = r.Headers["Record-Route"]; //foreach (Header h in InviteRecordRoute) //{ // h.Name = "Route"; //} } if (!r.Headers.ContainsKey("Via")) { Debug.Assert(false, String.Format("No Via header in received response \n{0}\n", r)); return; } string branch = r.Headers["Via"][0].Attributes["branch"]; string method = r.Headers["CSeq"][0].Method; Transaction t = FindTransaction(Transaction.CreateId(branch, method)); if (t == null) { if ((method == "INVITE") && (r.Is2XX())) { _log.Debug("Looking for dialog with ID " + Dialog.ExtractID(r)); foreach (KeyValuePair <string, Dialog> keyValuePair in Dialogs) { _log.Debug("Current Dialogs " + keyValuePair.Key); } Dialog d = FindDialog(r); if (d == null) { Debug.Assert(false, String.Format("No transaction or dialog for 2xx of INVITE \n{0}\n", r)); return; } else { d.ReceivedResponse(null, r); } } else { Console.WriteLine("No Transaction for response...ignoring...."); //Debug.Assert(false, String.Format("No Transaction for response \n{0}\n", r.ToString())); return; } } else { t.ReceivedResponse(r); return; } }
/// <summary> /// Handle received request /// </summary> /// <param name="m">The received message.</param> /// <param name="uri">The SIPURI that sent the message.</param> private void ReceivedRequest(Message m, SIPURI uri) { string branch = m.Headers["Via"][0].Attributes["branch"]; Transaction t; if (m.Method == "ACK") { if (branch == "0") { t = null; } else { t = FindTransaction(branch); if (t == null || (t.LastResponse != null && t.LastResponse.Is2XX())) { t = FindTransaction(Transaction.CreateId(branch, m.Method)); } } } else { t = FindTransaction(Transaction.CreateId(branch, m.Method)); } if (t == null) { UserAgent app = null; // Huh ? if ((m.Method != "CANCEL") && (m.Headers["To"][0].Attributes.ContainsKey("tag"))) { //In dialog request Dialog d = FindDialog(m); if (d == null) { if (m.Method != "ACK") { //Updated from latest code TODO UserAgent u = CreateServer(m, uri); if (u != null) { app = u; } else { // TODO: FIX NOTIFY ON SUBSCRIBE HANDLING if (m.Method != "NOTIFY") { Send(Message.CreateResponse(481, "Dialog does not exist", null, null, m)); return; } else { string branchID = m.Headers["Via"][0].Attributes["branch"]; if (_seenNotifys.ContainsKey(branchID) && _seenNotifys[branchID] > 1) { Send(Message.CreateResponse(481, "Dialog does not exist", null, null, m)); return; } else { if (_seenNotifys.ContainsKey(branchID)) { _seenNotifys[branchID] = _seenNotifys[branchID] + 1; } else { _seenNotifys[branchID] = 1; } } } return; } } else { _log.Info("No dialog for ACK, finding transaction"); if (t == null && branch != "0") { t = FindTransaction(Transaction.CreateId(branch, "INVITE")); } if (t != null && t.State != "terminated") { t.ReceivedRequest(m); return; } else { _log.Info("No existing transaction for ACK \n"); UserAgent u = CreateServer(m, uri); if (u != null) { app = u; } else { return; } } } } else { app = d; } } else if (m.Method != "CANCEL") { //Out of dialog request UserAgent u = CreateServer(m, uri); if (u != null) { //TODO error..... app = u; } else if (m.Method == "OPTIONS") { //Handle OPTIONS Message reply = Message.CreateResponse(200, "OK", null, null, m); reply.InsertHeader(new Header("INVITE,ACK,CANCEL,BYE,OPTION,MESSAGE,PUBLISH", "Allow")); Send(m); return; } else if (m.Method == "MESSAGE") { //Handle MESSAGE UserAgent ua = new UserAgent(this) { Request = m }; /*Message reply = ua.CreateResponse(200, "OK"); * Send(reply);*/ App.ReceivedRequest(ua, m, this); return; } else if (m.Method == "PUBLISH") { UserAgent ua = new UserAgent(this) { Request = m }; App.ReceivedRequest(ua, m, this); return; } else if (m.Method != "ACK") { Send(Message.CreateResponse(405, "Method not allowed", null, null, m)); return; } } else { //Cancel Request Transaction o = FindTransaction(Transaction.CreateId(m.Headers["Via"][0].Attributes["branch"], "INVITE")); if (o == null) { Send(Message.CreateResponse(481, "Original transaction does not exist", null, null, m)); return; } app = o.App; } if (app != null) { //t = Transaction.CreateServer(app.Stack, app, app.Request, app.Stack.Transport, app.Stack.Tag); // TODO: Check app or this ? t = Transaction.CreateServer(this, app, m, Transport, Tag); } else if (m.Method != "ACK") { Send(Message.CreateResponse(404, "Not found", null, null, m)); } } else { t.ReceivedRequest(m); } }