From e2bc6f4153813cc570ae814c8ddb74628009b488 Mon Sep 17 00:00:00 2001 From: Michal Kubecek Date: Mon, 13 Apr 2015 09:21:39 +0200 Subject: initial checkin Check in contents of upstream 1.4.2 tarball, exclude generated files. --- src/dialog.h | 845 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 845 insertions(+) create mode 100644 src/dialog.h (limited to 'src/dialog.h') diff --git a/src/dialog.h b/src/dialog.h new file mode 100644 index 0000000..7466d22 --- /dev/null +++ b/src/dialog.h @@ -0,0 +1,845 @@ +/* + Copyright (C) 2005-2009 Michel de Boer + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/** + * @file + * SIP dialog established by an INVITE transaction. + */ + +#ifndef _DIALOG_H +#define _DIALOG_H + +#include +#include +#include +#include +#include "abstract_dialog.h" +#include "client_request.h" +#include "phone.h" +#include "transaction_layer.h" +#include "protocol.h" +#include "redirect.h" +#include "session.h" +#include "user.h" +#include "sockets/url.h" +#include "threads/mutex.h" +#include "parser/request.h" +#include "sdp/sdp.h" +#include "stun/stun.h" + +using namespace std; + +// Forward declarations +class t_phone; +class t_line; +class t_session; +class t_sub_refer; + +/** Dialog state */ +enum t_dialog_state { + DS_NULL, /**< Initial state */ + + // UAC states + DS_W4INVITE_RESP, /**< INVITE sent, waiting for response */ + DS_W4INVITE_RESP2, /**< Provisional response received */ + DS_EARLY, /**< Provisional response with to-tag received */ + DS_W4BYE_RESP, /**< BYE sent, waiting for response */ + + // UAS states + DS_W4ACK, /**< Waiting for ACK on 2XX INVITE */ + DS_W4ANSWER, /**< INVITE received, waiting for user to answer */ + + // UAS and UAC states + DS_CONFIRMED, /**< Success received/sent */ + DS_W4ACK_RE_INVITE, /**< Waiting for ACK on re-INVITE */ + DS_W4RE_INVITE_RESP, /**< re-INVITE sent, waiting for response */ + DS_W4RE_INVITE_RESP2, /**< re-INVITE sent, provisional response recvd */ + DS_TERMINATED, /**< Dialog terminated */ + + // Subscription states + DS_CONFIRMED_SUB, /**< Confirmed refer-subscription dialog */ +}; + +/** Purpose for sending a re-INVITE request */ +enum t_reinvite_purpose { + REINVITE_HOLD, /**< Re-invite for call hold */ + REINVITE_RETRIEVE, /**< Re-invite for call retrieve */ +}; + +/** + * SIP dialog established by an INVITE transaction. + * + * Dialog state diagrams: + * @dot + * digraph call { + * label="Call setup and tear down state transitions" + * node [shape=ellipse, fontname=Helvetica, fontsize=10, style=filled, fillcolor=yellow]; + * edge [fontname=Helvetica, fontsize=9]; + * + * null [label="DS_NULL" URL="\ref DS_NULL"]; + * w4invite_resp [label="DS_W4INVITE_RESP" URL="\ref DS_W4INVITE_RESP"] + * w4invite_resp2 [label="DS_W4INVITE_RESP2" URL="\ref DS_W4INVITE_RESP2"] + * early [label="DS_EARLY" URL="\ref DS_EARLY"] + * w4bye_resp [label="DS_W4BYE_RESP" URL="\ref DS_W4BYE_RESP"] + * w4ack [label="DS_W4ACK" URL="\ref DS_W4ACK"] + * w4answer [label="DS_W4ANSWER" URL="\ref DS_W4ANSWER"] + * confirmed [label="DS_CONFIRMED" URL="\ref DS_CONFIRMED"] + * terminated [label="DS_TERMINATED" URL="\ref DS_TERMINATED"] + * + * null -> w4invite_resp [label="send INVITE"] + * null -> w4answer [label="receive INVITE"] + * null -> terminated [label="receive INVITE\nSTUN media\nbind fails"] + * null -> terminated [label="receive INVITE\nunsupported\nmedia or body"] + * w4invite_resp -> w4invite_resp2 [label="receive 1XX without to-tag"] + * w4invite_resp -> early [label="receive 1XX with to-tag"] + * w4invite_resp -> confirmed [label="receive 2XX"] + * w4invite_resp -> terminated [label="receive failure\nresponse"] + * w4invite_resp2 -> confirmed [label="receive 2XX"] + * w4invite_resp2 -> early [label="receive 1XX with to-tag"] + * w4invite_resp2 -> terminated [label="receive failure\nresponse"] + * early -> confirmed [label="receive 2XX"] + * early -> terminated [label="receive failure\nresponse"] + * w4answer -> w4ack [label="user answered, send 2XX"] + * w4answer -> terminated [label="user rejected\nsend 4XX/6XX"] + * w4answer -> terminated [label="receive CANCEL/BYE\nsend 487"] + * w4ack -> confirmed [label="receive ACK"] + * confirmed -> w4bye_resp [label="send BYE"] + * confirmed -> terminated [label="receive BYE"] + * w4bye_resp -> terminated [label="receive BYE response"] + * } + * @enddot + * + * @dot + * digraph reinvite { + * label="re-INVITE state transitions" + * node [shape=ellipse, fontname=Helvetica, fontsize=10, style=filled, fillcolor=yellow]; + * edge [fontname=Helvetica, fontsize=9]; + * + * confirmed [label="DS_CONFIRMED" URL="\ref DS_CONFIRMED"] + * w4ack_re_invite [label="DS_W4ACK_RE_INVITE" URL="\ref DS_W4ACK_RE_INVITE"] + * w4re_invite_resp [label="DS_W4RE_INVITE_RESP" URL="\ref DS_W4RE_INVITE_RESP"] + * w4re_invite_resp2 [label="DS_W4RE_INVITE_RESP2" URL="\ref DS_W4RE_INVITE_RESP2"] + * terminated [label="DS_TERMINATED" URL="\ref DS_TERMINATED"] + * + * confirmed -> w4ack_re_invite [label="receive re-INVITE, send 2XX"] + * confirmed -> terminated [label="receive re-INVITE\nSTUN fails"] + * confirmed -> confirmed [label="receive re-INVITE, send failure response"] + * confirmed -> w4re_invite_resp [label="send re-INVITE"] + * w4ack_re_invite -> confirmed [label="reveive ACK"] + * w4re_invite_resp -> w4re_invite_resp2 [label="receive 1XX"] + * w4re_invite_resp -> confirmed [label="receive final response"] + * w4re_invite_resp2 -> confirmed [label="receive final response"] + * w4re_invite_resp -> terminated [label="receive BYE"] + * w4re_invite_resp2 -> terminated [label="receive BYE"] + * } + * @enddot + * + * @dot + * digraph refer { + * label="State transitions when REFER subscription is active" + * node [shape=ellipse, fontname=Helvetica, fontsize=10, style=filled, fillcolor=yellow]; + * edge [fontname=Helvetica, fontsize=9]; + * + * confirmed [label="DS_CONFIRMED" URL="\ref DS_CONFIRMED"] + * w4bye_resp [label="DS_W4BYE_RESP" URL="\ref DS_W4BYE_RESP"] + * w4re_invite_resp [label="DS_W4RE_INVITE_RESP" URL="\ref DS_W4RE_INVITE_RESP"] + * w4re_invite_resp2 [label="DS_W4RE_INVITE_RESP2" URL="\ref DS_W4RE_INVITE_RESP2"] + * terminated [label="DS_TERMINATED" URL="\ref DS_TERMINATED"] + * confirmed_sub [label="DS_CONFIRMED_SUB" URL="DS_CONFIRMED_SUB"] + * + * confirmed -> confirmed_sub [label="receive BYE"] + * w4re_invite_resp -> confirmed_sub [label="receive BYE"] + * w4re_invite_resp2 -> confirmed_sub [label="receive BYE"] + * w4bye_resp -> confirmed_sub [label="receive BYE response"] + * confirmed_sub -> terminated [label="terminate subscription"] + * } + * @enddot + * + * @dot + * digraph timeout { + * label="State transitions due to timeouts" + * node [shape=ellipse, fontname=Helvetica, fontsize=10, style=filled, fillcolor=yellow]; + * edge [fontname=Helvetica, fontsize=9]; + * + * w4answer [label="DS_W4ANSWER" URL="\ref DS_W4ANSWER"] + * w4ack [label="DS_W4ACK" URL="\ref DS_W4ACK"] + * confirmed [label="DS_CONFIRMED" URL="\ref DS_CONFIRMED"] + * terminated [label="DS_TERMINATED" URL="\ref DS_TERMINATED"] + * confirmed_sub [label="DS_CONFIRMED_SUB" URL="DS_CONFIRMED_SUB"] + * + * w4answer -> w4answer [label="LTMR_100REL_TIMEOUT\nretransmit 1XX" URL="LTMR_100REL_TIMEOUT"] + * w4answer -> terminated [label="LTMR_100REL_GUARD\nsend 500" URL="LTMR_100REL_GUARD"] + * w4ack -> w4ack [label="LTMR_ACK_TIMEOUT\nretransmit 2XX" URL="LTMR_ACK_TIMEOUT"] + * w4ack -> confirmed [label="LTMR_ACK_GUARD\ntear down call" URL="LTMR_ACK_GUARD"] + * confirmed_sub -> terminated [label="REFER subscription\ntimeout"] + * } + * @enddot + */ +class t_dialog : public t_abstract_dialog { + friend class t_phone; + +protected: + t_line *line; /**< Phone line owning this dialog. */ + t_dialog_state state; /**< Dialog state. */ + + /** Session established by this dialog. */ + t_session *session; + + /** + * New session being established during re-invite. + * When the re-INVITE transaction finishes successfully, then + * this session information will override the general session. + */ + t_session *session_re_invite; + + /** The purpose of an outgoing re-INVITE request */ + t_reinvite_purpose reinvite_purpose; + + /** Indicates if the last call hold action failed. */ + bool hold_failed; + + t_client_request *req_out; /**< Pending outgoing non-INVITE request */ + t_client_request *req_out_invite; /**< Pending outgoing INVITE */ + t_client_request *req_in_invite; /**< Pending incoming INVITE */ + t_client_request *req_cancel; /**< Pending outgoing CANCEL */ + t_client_request *req_refer; /**< Pending outgoing REFER */ + t_client_request *req_info; /**< Pending outgoing INFO */ + + /** + * Last outgoing PRACK. While a PRACK is still pending a new 1xx + * response might come in. A PRACK will be sent for this 1xx without + * waiting for the response for the previous PRACK. + */ + t_client_request *req_prack; + + /** Pending STUN request */ + t_client_request *req_stun; + + /** + * Incoming request queue. A request may come in when it cannot be + * served yet. Such a request is stored in the queue to be served + * later. + */ + list inc_req_queue; + + /** Indication if request must be cancelled */ + bool request_cancelled; + + /** + * Indication that the dialog must be terminated after a 2XX + * on an INVITE is received (e.g. when 2XX glares with CANCEL). + */ + bool end_after_2xx_invite; + + /** Indication that the dialog must be terminated after ACK. */ + bool end_after_ack; + + /** + * Indication that the user wants to answer the call. + * Sending the answer must be delayed as we are still waiting for + * a PRACK to acknowledge a 1xx containing SDP from the + * far end (RFC 3262 3). + */ + bool answer_after_prack; + + /** Indication if 180 ringing has already been received */ + bool ringing_received; + + /** Cached success response to INVITE needed for retransmission */ + t_response *resp_invite; + + /** + * Cached provisional response to INVITE needed for retransmission + * when provisional responses are sent reliable (100rel) + */ + t_response *resp_1xx_invite; + + /** Cached ack needed for retransmission */ + t_request *ack; + + /** Subscription created by REFER (RFC 3515) */ + t_sub_refer *sub_refer; + + /** Queue of DTMF digits to be sent via INFO requests */ + queue dtmf_queue; + + /** @name Process incoming responses */ + //@{ + /** + * Process an incoming response in the @ref DS_W4INVITE_RESP state. + * @param r The response + * @param tuid Transaction user id + * @param tid Transaction id + */ + void state_w4invite_resp(t_response *r, t_tuid tuid, t_tid tid); + + /** + * Process an incoming response in the @ref DS_EARLY state. + * @param r The response + * @param tuid Transaction user id + * @param tid Transaction id + */ + void state_early(t_response *r, t_tuid tuid, t_tid tid); + + /** + * Process an incoming response in the @ref DS_W4BYE_RESP state. + * @param r The response + * @param tuid Transaction user id + * @param tid Transaction id + */ + void state_w4bye_resp(t_response *r, t_tuid tuid, t_tid tid); + + /** + * Process an incoming response in the @ref DS_CONFIRMED state. + * @param r The response + * @param tuid Transaction user id + * @param tid Transaction id + */ + void state_confirmed_resp(t_response *r, t_tuid tuid, t_tid tid); + + /** + * Process an incoming response in the @ref DS_W4RE_INVITE_RESP state. + * @param r The response + * @param tuid Transaction user id + * @param tid Transaction id + */ + void state_w4re_invite_resp(t_response *r, t_tuid tuid, t_tid tid); + //@} + + /** @name Process incoming requests */ + //@{ + /** + * Process an incoming request in the @ref DS_NULL state. + * @param r The request + * @param tuid Transaction user id + * @param tid Transaction id + */ + void state_null(t_request *r, t_tuid tuid, t_tid tid); + + /** + * Process an incoming request in the @ref DS_W4ANSWER state. + * @param r The request + * @param tuid Transaction user id + * @param tid Transaction id + */ + void state_w4answer(t_request *r, t_tuid tuid, t_tid tid); + + /** + * Process an incoming request in the @ref DS_W4ACK state. + * @param r The request + * @param tuid Transaction user id + * @param tid Transaction id + */ + void state_w4ack(t_request *r, t_tuid tuid, t_tid tid); + + /** + * Process an incoming request in the @ref DS_W4ACK_RE_INVITE state. + * @param r The request + * @param tuid Transaction user id + * @param tid Transaction id + */ + void state_w4ack_re_invite(t_request *r, t_tuid tuid, t_tid tid); + + /** + * Process an incoming request in the @ref DS_W4RE_INVITE_RESP state. + * @param r The request + * @param tuid Transaction user id + * @param tid Transaction id + */ + void state_w4re_invite_resp(t_request *r, t_tuid tuid, t_tid tid); + + /** + * Process an incoming request in the @ref DS_W4BYE_RESP state. + * @param r The request + * @param tuid Transaction user id + * @param tid Transaction id + */ + void state_w4bye_resp(t_request *r, t_tuid tuid, t_tid tid); + + /** + * Process an incoming request in the @ref DS_CONFIRMED state. + * @param r The request + * @param tuid Transaction user id + * @param tid Transaction id + */ + void state_confirmed(t_request *r, t_tuid tuid, t_tid tid); + + /** + * Process an incoming request in the @ref DS_CONFIRMED_SUB state. + * @param r The request + * @param tuid Transaction user id + * @param tid Transaction id + */ + void state_confirmed_sub(t_request *r, t_tuid tuid, t_tid tid); + //@} + + /** @name Process requests in the confirmed state */ + //@{ + /** Proces incoming re-INVITE. */ + void process_re_invite(t_request *r, t_tuid tuid, t_tid tid); + + /** Proces incoming REFER. */ + void process_refer(t_request *r, t_tuid tuid, t_tid tid); + + /** Process incoming SUBSCRIBE (refer subscription). */ + void process_subscribe(t_request *r, t_tuid tuid, t_tid tid); + + /** Process incoming NOTIFY (refer subscription). */ + void process_notify(t_request *r, t_tuid tuid, t_tid tid); + + /** Process incoming INFO. */ + void process_info(t_request *r, t_tuid tuid, t_tid tid); + + /** Process incoming MESSAGE. */ + void process_message(t_request *r, t_tuid tuid, t_tid tid); + //@} + + /** @name Process timeouts */ + //@{ + /** + * Process timeout in @ref DS_W4INVITE_RESP state. + * @param timer The expired timer. + */ + void state_w4invite_resp(t_line_timer timer); + + /** + * Process timeout in @ref DS_EARLY state. + * @param timer The expired timer. + */ + void state_early(t_line_timer timer); + + /** + * Process timeout in @ref DS_W4ACK state. + * @param timer The expired timer. + */ + void state_w4ack(t_line_timer timer); + + /** + * Process timeout in @ref DS_W4ACK_RE_INVITE state. + * @param timer The expired timer. + */ + void state_w4ack_re_invite(t_line_timer timer); + + /** + * Process timeout in @ref DS_W4RE_INVITE_RESP state. + * @param timer The expired timer. + */ + void state_w4re_invite_resp(t_line_timer timer); + + /** + * Process timeout in @ref DS_W4ANSWER state. + * @param timer The expired timer. + */ + void state_w4answer(t_line_timer timer); + + /** + * Process timeout in @ref DS_CONFIRMED state. + * @param timer The expired timer. + */ + void state_confirmed(t_line_timer timer); + //@} + + /** Make the re-INVITE session the current session. */ + void activate_new_session(void); + + /** + * Process SDP answer in 1xx and 2xx responses if present. + * Apply ringing tone for a 180 response. + * Determine if call should be canceled due to unsupported + * or missing SDP. + * @param r The 1XX/2XX response. + */ + void process_1xx_2xx_invite_resp(t_response *r); + + /** + * Acknowledge a reveived 2xx response on an INVITE. + * @param r The 2XX response. + */ + void ack_2xx_invite(t_response *r); + + /** + * Send PRACK if the response requires it. + * @param r The response. + */ + void send_prack_if_required(t_response *r); + + /** + * Determine if a reliable provisional repsonse must be discarded. + * A provisional response must be discarded because it is a retransmission + * or received out of order. + * Initializes the remote response nr if the response is the + * first response. + * @param r The provisional response. + * @return true, discard response. + * @return false, otherwise + */ + bool must_discard_100rel(t_response *r); + + /** + * Respond to an incoming PRACK. + * @param r The incoming PRACK. + * @param tuid Transaction user id + * @param tid Transaction id + * @return true, if a success response was given. + * @return false if an error response was given. + */ + bool respond_prack(t_request *r, t_tuid tuid, t_tid tid); + + virtual void send_request(t_request *r, t_tuid tuid); +public: + /** @name Timer durations and timer id's */ + //@{ + unsigned long dur_ack_timeout; /**< @ref LTMR_ACK_TIMEOUT duration (ms) */ + t_object_id id_ack_timeout; /**< @ref LTMR_ACK_TIMEOUT timer id */ + t_object_id id_ack_guard; /**< @ref LTMR_ACK_GUARD timer id */ + t_object_id id_re_invite_guard; /**< @ref LTMR_RE_INVITE_GUARD timer id */ + t_object_id id_glare_retry; /**< @ref LTMR_GLARE_RETRY timer id */ + t_object_id id_cancel_guard; /**< @ref LTMR_CANCEL_GUARD timer id */ + //@} + + /** @name RFC 3262 100rel timers */ + //@{ + unsigned long dur_100rel_timeout; /**< @ref LTMR_100REL_TIMEOUT duration (ms) */ + t_object_id id_100rel_timeout; /**< @ref LTMR_100REL_TIMEOUT timer id */ + t_object_id id_100rel_guard; /**< @ref LTMR_100REL_GUARD timer id */ + //@} + + /** Indicates if last incoming REFER was accepted. */ + bool refer_accepted; + + /** Indicates if the call transfer triggered by the last outgoing REFER succeeded. */ + bool refer_succeeded; + + /** Indicates if the last outgoing REFER request failed. */ + bool out_refer_req_failed; + + /** + * Indicates if this dialog is setup because the user told to do + * so by a REFER. + */ + bool is_referred_call; + + /** State of an outgoing REFER. */ + t_refer_state refer_state; + + /** + * Constructor. + * @param _line The line owning this dialog. + */ + t_dialog(t_line *_line); + + /** Destructor. */ + virtual ~t_dialog(); + + virtual t_request *create_request(t_method m); + + virtual t_dialog *copy(void); + + /** + * Send INIVTE request. + * @param to_uri The URI to be used a request-URI and To header URI + * @param to_display Display name for To header. + * @param subject If not empty, this string will go into the Subject header. + * @param hdr_referred_by The Reffered-By header to be put in the INVITE. + * @param hdr_replaces The Replaces header to be put in the INVITE. + * @param hdr_require Required extensions to be put in the Require header. + * @param hdr_request_disposition Request-Disposition header to be put in the INVITE. + * @param anonymous Inidicates if the INVITE should be sent anonymous. + * + * @pre Dialog is in @ref DS_NULL state. + */ + void send_invite(const t_url &to_uri, const string &to_display, + const string &subject, const t_hdr_referred_by &hdr_referred_by, + const t_hdr_replaces &hdr_replaces, + const t_hdr_require &hdr_require, + const t_hdr_request_disposition &hdr_request_disposition, + bool anonymous); + + /** + * Resend the INVITE with an authorization header containing credentials + * for the challenge in the response. + * @param resp, the response on the INVITE. + * @return true, if resending succeeded. + * @return false, if credentials could not be determined. + * + * @pre The response must be a 401 or 407. + */ + bool resend_invite_auth(t_response *resp); + + /** + * Resend the INVITE because the far-end did not support all required + * extensions. Extensions that could not be supported will not be + * required this time. + * @param resp The response in the INVITE. + * @return true, if resending succeeded. + * @return false, if far-end did not indicate which extensions are + * unsupported. Or if a required extension could not be disabled. + * + * @pre The response must be a 420. + */ + bool resend_invite_unsupported(t_response *resp); + + /** + * Redirect INVITE to the next destination. + * @param resp The response on the INVITE. + * @return true, if INIVTE was redirected succesfully. + * @return false, if there is no next destination. + * + * @pre The response must be a 3XX. + */ + bool redirect_invite(t_response *resp); + + /** + * Failover INVITE to the next destination from DNS lookup. + * @return true, if INIVTE was succesfully sent. + * @return false, if there is no next destination. + */ + bool failover_invite(void); + + /** Send BYE request. */ + void send_bye(void); + + /** Send OPTIONS request. */ + void send_options(void); + + /** + * Send CANCEL request. + * If an early dialog exists, then the CANCEL can be sent + * right away as a response has been received for the INVITE. + * Otherwise, the CANCEL will be sent as soon as an early dialog + * is created. + * @param early_dialog_exists Indicates if an early dialog exists. + */ + void send_cancel(bool early_dialog_exists); + + /** + * Indicate that the dialog must be ended if a 2XX is received + * on an INVITE. + * @param on Set/clear indication. + */ + void set_end_after_2xx_invite(bool on); + + /** + * Send re-INVITE. + * @pre session_re_invite attribute contains the session + * information for the re-INVITE. + */ + void send_re_invite(void); + + virtual bool resend_request_auth(t_response *resp); + + virtual bool redirect_request(t_response *resp); + + virtual bool failover_request(t_response *resp); + + /** + * Hold call. + * If rtp_only is false, then a re-INVITE will be sent. + * @param rtponly Indicates if only the RTP streams should be stopped and + * the soundcard freed without any SIP signaling. + */ + void hold(bool rtponly = false); + + /** Retrieve call (send re-INVITE if needed). */ + void retrieve(void); + + /** Kill all RTP stream associated with this dialog. */ + void kill_rtp(void); + + /** + * Refer a call (send REFER). + * @param uri URI of the refer target. + * @param display Display name of the refer target. + */ + void send_refer(const t_url &uri, const string &display); + + /** + * Send DTMF digit. + * @param digit The digit. + * @param inband Indicates if digit must be sent inband. + * @param info Indicates if digit must be sent in a SIP INFO. + * + * @pre Either inband or info or none of the indicators is true. + * @post If none of the indicators is true, then RFC 2833 is used. + */ + void send_dtmf(char digit, bool inband, bool info); + + /** + * Create a binding for the media port via STUN. + * @return true, if binding is created. + * @return false, if binding cannot be created. + */ + bool stun_bind_media(void); + + /** @name Handle received events */ + //@{ + void recvd_response(t_response *r, t_tuid tuid, t_tid tid); + + void recvd_request(t_request *r, t_tuid tuid, t_tid tid); + + /** + * Handle incoming CANCEL request. + * @param r The CANCEL request. + * @param cancel_tid Transaction id of the CANCEL transaction. + * @param target_tid Transaction id of the transaction to be cancellerd. + */ + void recvd_cancel(t_request *r, t_tid cancel_tid, t_tid target_tid); + + /** + * Handle incoming STUN response. + * @param r The STUN response. + * @param tuid Transaction user id + * @param tid Transaction id + */ + void recvd_stun_resp(StunMessage *r, t_tuid tuid, t_tid tid); + + /** + * Handle the response from the user on the question for refer + * permission. This response is received on the dialog that received + * the REFER before. + * @param permission Permission response from the user. + * @param r The REFER request that was received. + */ + void recvd_refer_permission(bool permission, t_request *r); + //@} + + /** Answer a call (send 200 OK). */ + void answer(void); + + /** + * Reject a call. + * @param code The response code to reject the call with. + * @param reason A specific reason may be given to the error code. If no + * reason is specified the default reason is used. + * + * @pre code >= 400 + */ + void reject(int code, string reason = ""); + + /** + * Redirect a call. + * @param code The response code to redirect the call with. + * @param A specific reason may be give to the error code. If no + * reason is specified the default reason is used. + * @param destinations The list of redirect destinations in order of + * preference. + * + * @pre code is 3XX. + */ + void redirect(const list &destinations, int code, string reason = ""); + + virtual bool match_response(t_response *r, t_tuid tuid); + + /** + * Match STUN response with dialog. + * @param r STUN response. + * @param tuid Transaction user id + * @return true, if response matches. + * @return false, otherwise. + */ + bool match_response(StunMessage *r, t_tuid tuid); + + /** + * Match CANCEL request with dialog. + * @param r CANCEL request. + * @param target_tid Transaction id of transaction to be cancelled. + * @return true, if request matches. + * @return false, otherwise. + */ + bool match_cancel(t_request *r, t_tid target_tid); + + /** + * Check if an incoming INVITE is a retransmission. + * @param r The INVITE request. + * @return true, if INVITE is a retransmission. + * @return false, otherwise. + */ + bool is_invite_retrans(t_request *r); + + /** Process a retransmission of an incoming INVITE. */ + void process_invite_retrans(void); + + /** + * Get the state of the dialog. + * @return The dialog state. + */ + t_dialog_state get_state(void) const; + + /** + * Process dialog timer timeout. + * @param timer The timer that expired. + */ + void timeout(t_line_timer timer); + + /** + * Process subcribe timer timeout (REFER subscription). + * @param timer The timer that expired. + * @param event_type Event type of the subscription. + * @param event_id Event id of the subscription. + */ + void timeout_sub(t_subscribe_timer timer, const string &event_type, + const string &event_id); + + /** + * Get the phone that belongs to this dialog. + * @return The phone object. + */ + t_phone *get_phone(void) const; + + /** + * Get the line that belongs to this dialog. + * @return The line object. + */ + t_line *get_line(void) const; + + /** + * Get the session belonging to this dialog. + * @return The session belonging to this dialog. + * @return NULL if there is no session. + */ + t_session * get_session(void) const; + + /** + * Get the audio session belonging to this dialog. + * @return The audio session belonging to this dialog. + * @return NULL if there is no audio session. + */ + t_audio_session *get_audio_session(void) const; + + /** + * Check if the dialog has an acitve session. + * @return true, if the dialog has an active session. + * @return false, otherwise. + */ + bool has_active_session(void) const; + + /** + * Notify the dialog of the progress of a reference. + * @param r The response sent by the refer target. + */ + void notify_refer_progress(t_response *r); + + /** + * Check if a dialog will be released. + * @return true, if the dialog will be released. + * @return false, otherwise. + */ + bool will_release(void) const; +}; + +#endif -- cgit v1.2.3