/* 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, see . */ /** * @file * Abstract class for all types of SIP dialogs. */ #ifndef _ABSTRACT_DIALOG_H #define _ABSTRACT_DIALOG_H #include #include #include #include #include "client_request.h" #include "id_object.h" #include "protocol.h" #include "sockets/url.h" #include "parser/request.h" using namespace std; // Forward declaration class t_phone_user; /** * Abstract class for all types of SIP dialogs. * Concrete classes for all SIP dialogs inherit from this class. */ class t_abstract_dialog : public t_id_object { protected: /** * Phone user for which this dialog is created. * This pointer should never be deleted. */ t_phone_user *phone_user; string call_id; /**< SIP call id. */ bool call_id_owner; /**< Indicates if the call id is generated locally. */ string local_tag; /**< Local tag value. */ string remote_tag; /**< Remote tag value. */ unsigned long local_seqnr; /**< Last local sequence number issued. */ unsigned long remote_seqnr; /**< Last remote sequence number received. */ /** * The remote_seqnr_set indicates if the remote_seqnr is set by the far-end. * RFC 3261 allows the CSeq sequence number to be 0. So there is no * invalid sequence number. */ bool remote_seqnr_set; t_url local_uri; /**< URI of the local party (From/To headers). */ string local_display; /**< Display name of the local party. */ t_url remote_uri; /**< URI of the remote party (From/To headers). */ string remote_display; /**< Display name of the remote party. */ /** URI of the remote target (Contact header). This is the destination for a request. */ t_url remote_target_uri; string remote_target_display; /**< Display name of the remote target. */ list route_set; /**< The route set. */ unsigned long local_resp_nr; /**< Last local response number (for 100rel) issued. */ unsigned long remote_resp_nr; /**< Last remote response number (for 100rel) received. */ set remote_extensions; /**< SIP extensions supported by the remote party. */ /** The IP transport/address/port from which the last SIP message was received. */ t_ip_port remote_ip_port; /** * Remove a client request. Pass one of the client request * pointers to this member. The reference count of the * request will be decremented. If it becomes zero, then * the request object is deleted. * In all cases the passed pointer will be set to NULL. * @param cr [in] The client request. */ void remove_client_request(t_client_request **cr); /** * Create route set from the Record-Route header of a response. * If the response does not have a Record-Route header, then the route * set is cleared. * @param r [in] The response. */ void create_route_set(t_response *r); /** * Create remote target uri and display from the Contact header of a response. * @param r [in] The response. */ void create_remote_target(t_response *r); /** * Send a request within the dialog. * Sending a request will create a SIP transaction. * @param r [in] The request. * @param tuid [in] The transaction user id to be assigend to the transaction. */ virtual void send_request(t_request *r, t_tuid tuid) = 0; /** * Resend an existing client request. * A new Via and CSeq header will be put in the request. * Resending is different from retransmitting. Requests are automatically * retransmitted by the transaction layer. Resending creates a new SIP * transaction. Resending is f.i. done when a request must be redirected. * @param cr [in] The client request. */ virtual void resend_request(t_client_request *cr); /** * Resend mid-dialog request with an authorization header containing * credentials for the challenge in the response. * @param cr [in] The request. * @param resp [in] The 401 or 407 response. * @return true, if resending succeeded. * @return false, if credentials could not be determined. * * @pre The response must be a 401 or 407. */ bool resend_request_auth(t_client_request *cr, t_response *resp); /** * Redirect mid-dialog request to the next destination. * There are multiple reasons for redirection: * - A 3XX response was received. * - The request failed with a non-3XX response. A next contact should be tried. * * @param cr [in] The request. * @param resp [in] The failure response that was received on the request. * @param contact [out] Contains on successful return the contact to which the request is sent. * @return true, if the request is sent to a next destination. * @return false, if no next destination exists. */ bool redirect_request(t_client_request *cr, t_response *resp, t_contact_param &contact); /** * Failover request to the next destination from DNS lookup. * @param cr [in] The request. * @return true, if the request is sent to a next destination. * @return false, if no next destination exists. */ bool failover_request(t_client_request *cr); public: /** * Constructor. * @param pu [in] Phone user for which the dialog must be created. */ t_abstract_dialog(t_phone_user *pu); /** * Destructor. */ virtual ~t_abstract_dialog(); /** * Create a request using the stored dialog state information. * @param m [in] Request method. * @return The request. */ virtual t_request *create_request(t_method m); /** * Copy a dialog. * @return A copy of the dialog. */ virtual t_abstract_dialog *copy(void) = 0; /** * Get a pointer to the user profile of the user for whom this dialog * was created. * @return The user profile. */ t_user *get_user(void) const; /** * Resend mid-dialog request with an authorization header containing * credentials for the challenge in the response. * @param resp [in] The 401 or 407 response to the request that must be resent. * @return true, if resending succeeded. * @return false, if credentials could not be determined. * * @pre The response must be a 401 or 407. */ virtual bool resend_request_auth(t_response *resp) = 0; /** * Redirect mid-dialog request to the next destination. * @param resp [in] The response to the request that must be resent. * @return true, if the request is sent to a next destination. * @return false, if no next destination exists. */ virtual bool redirect_request(t_response *resp) = 0; /** * Failover request to the next destination from DNS lookup. * @param resp [in] The response to the request that must be resent. * @return true, if the request is sent to a next destination. * @return false, if no next destination exists. */ virtual bool failover_request(t_response *resp) = 0; /** * Process a received response. * @param r [in] The received response. * @param tuid [in] The transaction user id of the transaction for the response. * @param tid [in] The transaction id of the transaction for the response. */ virtual void recvd_response(t_response *r, t_tuid tuid, t_tid tid); /** * Process a received request. * @param r [in] The received request. * @param tuid [in] The transaction user id of the transaction for the request. * @param tid [in] The transaction id of the transaction for the request. */ virtual void recvd_request(t_request *r, t_tuid tuid, t_tid tid); /** * Match a response with the dialog. * @param r [in] The response. * @param tuid [in] The transaction user id of the transaction for the response. * @return true, if the response matches the dialog. * @return false, otherwise. */ virtual bool match_response(t_response *r, t_tuid tuid); /** * Match a request with the dialog. * @param r [in] The request. * @return true, if the request matches the dialog. * @return false, otherwise. */ virtual bool match_request(t_request *r); /** * Partially match a request with the dialog, i.e. do not match remote tag. * @param r [in] The request. * @return true, if the request partially matches the dialog. * @return false, otherwise. */ virtual bool match_partial_request(t_request *r); /** * Match call-id and tags with the dialog. * @param _call_id [in] SIP call-id. * @param to_tag [in] SIP to-tag. * @param from_tag [in] SIP from-tag. * @return true, if call-id and tags match the dialog. * @return false, otherwise. */ virtual bool match(const string &_call_id, const string &to_tag, const string &from_tag) const; /** * Get the URI of the remote target. * @return remote target URI. * @see remote_target_uri */ t_url get_remote_target_uri(void) const; /** * Get the display name of the remote target. * @return display name of remote target. * @see remote_target_display */ string get_remote_target_display(void) const; /** * Get the URI of the remote party. * @return URI of remote party. * @see remote_uri */ t_url get_remote_uri(void) const; /** * Get the display name of the remote party. * @return display name of the remote party. * @see remote_display */ string get_remote_display(void) const; /** * Get the IP transport/address/port from which the last SIP message was received. * @return transport/address/port */ t_ip_port get_remote_ip_port(void) const; /** * Get the SIP call id. * @return SIP call id. */ string get_call_id(void) const; /** * Get the local tag. * @return local tag. */ string get_local_tag(void) const; /** * Get the remote tag. * @return remote tag. */ string get_remote_tag(void) const; /** * Check if the remote party supports a particular SIP exentsion. * @param extension [in] Name of the SIP extension. * @return true, if remote party supports the extension. * @return false, otherwise. */ virtual bool remote_extension_supported(const string &extension) const; /** * Check if this dialog is the owner of the call id. * @return true, if this dialog is the owner. * @return false, otherwise. * @see call_id_owner */ bool is_call_id_owner(void) const; }; #endif