Skip to content
This repository was archived by the owner on Feb 27, 2020. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions include/bgcfsproutlet.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,9 @@ class BGCFSproutletTsx : public SproutletTsx
~BGCFSproutletTsx();

virtual void on_rx_initial_request(pjsip_msg* req) override;
virtual void on_tx_request(pjsip_msg* req, int fork_id) override;
virtual void obs_tx_request(pjsip_msg* req, int fork_id, bool tsx_mgmt) override;
virtual void on_rx_response(pjsip_msg* rsp, int fork_id) override;
virtual void on_tx_response(pjsip_msg* rsp) override;
virtual void obs_tx_response(pjsip_msg* rsp, bool tsx_mgmt) override;
virtual void on_rx_cancel(int status_code, pjsip_msg* req) override;

private:
Expand Down
8 changes: 4 additions & 4 deletions include/icscfsproutlet.h
Original file line number Diff line number Diff line change
Expand Up @@ -154,9 +154,9 @@ class ICSCFSproutletTsx : public SproutletTsx

virtual void on_rx_initial_request(pjsip_msg* req) override;
virtual void on_rx_in_dialog_request(pjsip_msg* req) override;
virtual void on_tx_request(pjsip_msg* req, int fork_id) override;
virtual void obs_tx_request(pjsip_msg* req, int fork_id, bool tsx_mgmt) override;
virtual void on_rx_response(pjsip_msg* rsp, int fork_id) override;
virtual void on_tx_response(pjsip_msg* rsp) override;
virtual void obs_tx_response(pjsip_msg* rsp, bool tsx_mgmt) override;
virtual void on_rx_cancel(int status_code, pjsip_msg* req) override;

private:
Expand Down Expand Up @@ -200,9 +200,9 @@ class ICSCFSproutletRegTsx : public SproutletTsx

virtual void on_rx_initial_request(pjsip_msg* req) override;
virtual void on_rx_in_dialog_request(pjsip_msg* req) override;
virtual void on_tx_request(pjsip_msg* req, int fork_id) override;
virtual void obs_tx_request(pjsip_msg* req, int fork_id, bool tsx_mgmt) override;
virtual void on_rx_response(pjsip_msg* rsp, int fork_id) override;
virtual void on_tx_response(pjsip_msg* rsp) override;
virtual void obs_tx_response(pjsip_msg* rsp, bool tsx_mgmt) override;
virtual void on_rx_cancel(int status_code, pjsip_msg* req) override;

private:
Expand Down
12 changes: 12 additions & 0 deletions include/pjutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,18 @@ pjsip_tx_data* create_cancel(pjsip_endpoint* endpt,
pjsip_tx_data* tdata,
int reason_code);

/// Creates an ACK to a negative response. This method cannot be used to
/// generate ACKs for ACK transactions.
///
/// @return - The negative ACK created
///
/// @param endpt - The PJSIP endpoint.
/// @param req - The original request that the response was sent to.
/// @param rsp - The response to the original request.
pjsip_tx_data* create_ack(pjsip_endpoint* endpt,
pjsip_msg* req,
pjsip_msg* rsp);

void resolve(const std::string& name,
int port,
int transport,
Expand Down
9 changes: 7 additions & 2 deletions include/scscfsproutlet.h
Original file line number Diff line number Diff line change
Expand Up @@ -246,9 +246,10 @@ class SCSCFSproutletTsx : public SproutletTsx

virtual void on_rx_initial_request(pjsip_msg* req) override;
virtual void on_rx_in_dialog_request(pjsip_msg* req) override;
virtual void on_tx_request(pjsip_msg* req, int fork_id) override;
virtual void obs_tx_request(pjsip_msg* req, int fork_id, bool tsx_mgmt) override;
virtual void on_rx_response(pjsip_msg* rsp, int fork_id) override;
virtual void on_tx_response(pjsip_msg* rsp) override;
virtual void on_rx_trying(pjsip_msg* rsp, int fork_id) override;
virtual void obs_tx_response(pjsip_msg* rsp, bool tsx_mgmt) override;
virtual void on_rx_cancel(int status_code, pjsip_msg* req) override;
virtual void on_timer_expiry(void* context) override;

Expand Down Expand Up @@ -367,6 +368,10 @@ class SCSCFSproutletTsx : public SproutletTsx
/// @param sip_code - The reported SIP return code
std::string fork_failure_reason_as_string(int fork_id, int sip_code);

void acr_handle_response(pjsip_msg* rsp);

void cancel_liveness_timer();

/// Pointer to the parent SCSCFSproutlet object - used for various operations
/// that require access to global configuration or services.
SCSCFSproutlet* _scscf;
Expand Down
70 changes: 53 additions & 17 deletions include/sproutlet.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ class SproutletTsxHelper
///
/// @returns - A clone of the original request message.
///
virtual pjsip_msg* original_request() = 0;
virtual pjsip_msg* get_request_for_sproutlet_tsx() = 0;

/// Returns the top Route header from the original incoming request. This
/// can be inpsected by the Sproutlet, but should not be modified. Note that
Expand Down Expand Up @@ -321,28 +321,23 @@ class SproutletTsx
/// @param req - The received in-dialog request.
virtual void on_rx_in_dialog_request(pjsip_msg* req) { send_request(req); }

/// Called when a request has been transmitted on the transaction (usually
/// because the service has previously called forward_request() with the
/// request message.
/// Called with all responses, except 100 Trying, received on the transaction.
/// If a transport error or transaction timeout occurs on a downstream leg,
/// this method is called with a 408 response.
///
/// @param req - The transmitted request
/// @param fork_id - The identity of the downstream fork on which the
/// request was sent.
virtual void on_tx_request(pjsip_msg* req, int fork_id) { }

/// Called with all responses received on the transaction. If a transport
/// error or transaction timeout occurs on a downstream leg, this method is
/// called with a 408 response.
/// Note: 100 Trying responses are handled by the on_rx_trying method.
///
/// @param rsp - The received request.
/// @param rsp - The received response.
/// @param fork_id - The identity of the downstream fork on which
/// the response was received.
virtual void on_rx_response(pjsip_msg* rsp, int fork_id) { send_response(rsp); }

/// Called when a response has been transmitted on the transaction.
/// This is a notification that a 100 Trying has been received. The sproutlet
/// proxy handles these automatically. The Sproutlet Tsx should not forward
/// the response on (i.e. should not call send_request).
///
/// @param rsp - The transmitted response.
virtual void on_tx_response(pjsip_msg* rsp) { }
/// @param rsp - The received response.
virtual void on_rx_trying(pjsip_msg* rsp, int fork_id) {}

/// Called if the original request is cancelled (either by a received
/// CANCEL request, an error on the inbound transport or a transaction
Expand All @@ -357,6 +352,47 @@ class SproutletTsx
/// was triggered by an error or timeout.
virtual void on_rx_cancel(int status_code, pjsip_msg* cancel_req) {}

/// The next four methods make up the observation API. The purpose of this API
/// is to view transaction management messages that are not seen by
/// on_rx_request and on_rx_response. This includes CANCEL, 200 OK to CANCEL,
/// 100 Trying and ACK to negative response. This API also sees all the
/// messages that are passed to on_rx_request and on_rx_response.

/// Called when a request is received by this sproutlet Tsx.
///
/// @param req - The received request.
/// @param tsx_mgmt - True when the received request will not be passed
/// to on_rx_request.
virtual void obs_rx_request(pjsip_msg* req, bool tsx_mgmt) {};

/// Called when a response is received by this sproutlet Tsx.
///
/// @param rsp - The received response.
/// @param fork_id - The identity of the downstream fork on which the
/// response was received.
/// @param tsx_mgmt - True when the received respone will not be passed
/// to on_rx_response.
virtual void obs_rx_response(pjsip_msg* rsp, int fork_id, bool tsx_mgmt) {};

/// Called when a request has been transmitted on the transaction by this
/// sproutlet Tsx. This is usually because the service has previously called
/// forward_request() with the request message.
///
/// @param req - The transmitted request
/// @param fork_id - The identity of the downstream fork on which the
/// request was sent.
/// @param tsx_mgmt - True when the transmitted request was not generated
/// by the sproutlet Tsx calling send_request().
virtual void obs_tx_request(pjsip_msg* req, int fork_id, bool tsx_mgmt) {}

/// Called when a response has been transmitted on the transaction by the
/// sproutlet Tsx.
///
/// @param rsp - The transmitted response.
/// @param tsx_mgmt - True when the transmitted response was not generated
/// by the sproutlet Tsx calling send_response().
virtual void obs_tx_response(pjsip_msg* rsp, bool tsx_mgmt) {}

/// Called when a timer programmed by the SproutletTsx expires.
///
/// @param context - The context parameter specified when the timer
Expand All @@ -371,7 +407,7 @@ class SproutletTsx
/// @returns - A clone of the original request message.
///
pjsip_msg* original_request()
{return _helper->original_request();}
{return _helper->get_request_for_sproutlet_tsx();}

/// Returns a URI that could be used to route back to the current Sproutlet.
/// This URI may contain pre-loaded parameters that should not be modified
Expand Down
8 changes: 7 additions & 1 deletion include/sproutletproxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,10 @@ class SproutletProxy : public BasicProxy
int fork_id,
pjsip_tx_data* cancel);

void tx_negative_ack(SproutletWrapper* sproutlet,
int fork_id,
pjsip_tx_data* ack);

/// Gets the next target Sproutlet for the message by analysing the top
/// Route header.
Sproutlet* target_sproutlet(pjsip_msg* msg,
Expand Down Expand Up @@ -289,7 +293,7 @@ class SproutletWrapper : public SproutletTsxHelper
/// functions from SproutletTsxHelper. See there for function comments for
/// the following.
void add_to_dialog(const std::string& dialog_id="");
pjsip_msg* original_request();
pjsip_msg* get_request_for_sproutlet_tsx();
const char* msg_info(pjsip_msg*);
const pjsip_route_hdr* route_hdr() const;
const std::string& dialog_id() const;
Expand Down Expand Up @@ -320,6 +324,7 @@ class SproutletWrapper : public SproutletTsxHelper
void rx_request(pjsip_tx_data* req);
void rx_response(pjsip_tx_data* rsp, int fork_id);
void rx_cancel(pjsip_tx_data* cancel);
void rx_negative_ack(pjsip_tx_data* ack);
void rx_error(int status_code);
void rx_fork_error(pjsip_event_id_e event, int fork_id);
void on_timer_pop(TimerID id, void* context);
Expand All @@ -331,6 +336,7 @@ class SproutletWrapper : public SproutletTsxHelper
void tx_request(pjsip_tx_data* req, int fork_id);
void tx_response(pjsip_tx_data* rsp);
void tx_cancel(int fork_id);
void tx_negative_ack(pjsip_tx_data* rsp, int fork_id);
int compare_sip_sc(int sc1, int sc2);
bool is_uri_local(const pjsip_uri*) const;
void log_inter_sproutlet(pjsip_tx_data* tdata, bool downstream);
Expand Down
10 changes: 6 additions & 4 deletions src/bgcfsproutlet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -253,9 +253,10 @@ void BGCFSproutletTsx::on_rx_initial_request(pjsip_msg* req)
}


void BGCFSproutletTsx::on_tx_request(pjsip_msg* req, int fork_id)
void BGCFSproutletTsx::obs_tx_request(pjsip_msg* req, int fork_id, bool tsx_mgmt)
{
if (_acr != NULL)
// We don't send ACRs for transaction management messages.
if ((!tsx_mgmt) && (_acr != NULL))
{
// Pass the transmitted request to the ACR to update the accounting
// information.
Expand All @@ -279,9 +280,10 @@ void BGCFSproutletTsx::on_rx_response(pjsip_msg* rsp, int fork_id)
}


void BGCFSproutletTsx::on_tx_response(pjsip_msg* rsp)
void BGCFSproutletTsx::obs_tx_response(pjsip_msg* rsp, bool tsx_mgmt)
{
if (_acr != NULL)
// We don't send ACRs for transaction management messages.
if ((!tsx_mgmt) && (_acr != NULL))
{
// Pass the transmitted response to the ACR to update the accounting
// information.
Expand Down
113 changes: 60 additions & 53 deletions src/icscfsproutlet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -297,9 +297,10 @@ void ICSCFSproutletRegTsx::on_rx_in_dialog_request(pjsip_msg* req)
}


void ICSCFSproutletRegTsx::on_tx_request(pjsip_msg* req, int fork_id)
void ICSCFSproutletRegTsx::obs_tx_request(pjsip_msg* req, int fork_id, bool tsx_mgmt)
{
if (_acr != NULL)
// We don't send ACRs for transaction management messages.
if ((!tsx_mgmt) && (_acr != NULL))
{
// Pass the transmitted request to the ACR to update the accounting
// information.
Expand Down Expand Up @@ -393,9 +394,10 @@ void ICSCFSproutletRegTsx::on_rx_response(pjsip_msg* rsp, int fork_id)
}


void ICSCFSproutletRegTsx::on_tx_response(pjsip_msg* rsp)
void ICSCFSproutletRegTsx::obs_tx_response(pjsip_msg* rsp, bool tsx_mgmt)
{
if (_acr != NULL)
// We don't send ACRs for transaction management messages.
if ((!tsx_mgmt) && (_acr != NULL))
{
// Pass the transmitted response to the ACR to update the accounting
// information.
Expand Down Expand Up @@ -710,9 +712,10 @@ void ICSCFSproutletTsx::on_rx_in_dialog_request(pjsip_msg* req)
}


void ICSCFSproutletTsx::on_tx_request(pjsip_msg* req, int fork_id)
void ICSCFSproutletTsx::obs_tx_request(pjsip_msg* req, int fork_id, bool tsx_mgmt)
{
if (_acr != NULL)
// We don't send ACRs for transaction management messages.
if ((!tsx_mgmt) && (_acr != NULL))
{
// Pass the transmitted request to the ACR to update the accounting
// information.
Expand Down Expand Up @@ -799,60 +802,64 @@ void ICSCFSproutletTsx::on_rx_response(pjsip_msg* rsp, int fork_id)
}


void ICSCFSproutletTsx::on_tx_response(pjsip_msg* rsp)
void ICSCFSproutletTsx::obs_tx_response(pjsip_msg* rsp, bool tsx_mgmt)
{
if (_acr != NULL)
{
// Pass the transmitted response to the ACR to update the accounting
// information.
_acr->tx_response(rsp);
}

pjsip_status_code rsp_status = (pjsip_status_code)rsp->line.status.code;

// Check if this is a terminating INVITE. If it is then check whether we need
// to update our session establishment stats. We consider the session to be
// set up as soon as we receive a final response OR a 180 Ringing (per TS
// 32.409).
if (!_originating &&
(_req_type == PJSIP_INVITE_METHOD) &&
!_session_set_up &&
((rsp_status == PJSIP_SC_RINGING) ||
!PJSIP_IS_STATUS_IN_CLASS(rsp_status, 100)))
// We don't send ACRs or update stats for transaction management messages.
if (!tsx_mgmt)
{
// Session is now set up.
_session_set_up = true;
_icscf->_session_establishment_tbl->increment_attempts();
_icscf->_session_establishment_network_tbl->increment_attempts();

if ((rsp_status == PJSIP_SC_RINGING) ||
PJSIP_IS_STATUS_IN_CLASS(rsp_status, 200))
{
// Session has been set up successfully.
TRC_DEBUG("Session successful");
_icscf->_session_establishment_tbl->increment_successes();
_icscf->_session_establishment_network_tbl->increment_successes();
}
else if ((rsp_status == PJSIP_SC_BUSY_HERE) ||
(rsp_status == PJSIP_SC_BUSY_EVERYWHERE) ||
(rsp_status == PJSIP_SC_NOT_FOUND) ||
(rsp_status == PJSIP_SC_ADDRESS_INCOMPLETE))
if (_acr != NULL)
{
// Session failed, but should be counted as successful from a network
// perspective.
TRC_DEBUG("Session failed but network successful");
_icscf->_session_establishment_tbl->increment_failures();
_icscf->_session_establishment_network_tbl->increment_successes();
// Pass the transmitted response to the ACR to update the accounting
// information.
_acr->tx_response(rsp);
}
else

pjsip_status_code rsp_status = (pjsip_status_code)rsp->line.status.code;

// Check if this is a terminating INVITE. If it is then check whether we need
// to update our session establishment stats. We consider the session to be
// set up as soon as we receive a final response OR a 180 Ringing (per TS
// 32.409). We do not consider responses to CANCEL requests as final
// responses.
if (!_originating &&
(_req_type == PJSIP_INVITE_METHOD) &&
!_session_set_up &&
((rsp_status == PJSIP_SC_RINGING) ||
!PJSIP_IS_STATUS_IN_CLASS(rsp_status, 100)))
{
// Session establishment failed.
TRC_DEBUG("Session failed");
_icscf->_session_establishment_tbl->increment_failures();
_icscf->_session_establishment_network_tbl->increment_failures();
// Session is now set up.
_session_set_up = true;
_icscf->_session_establishment_tbl->increment_attempts();
_icscf->_session_establishment_network_tbl->increment_attempts();

if ((rsp_status == PJSIP_SC_RINGING) ||
PJSIP_IS_STATUS_IN_CLASS(rsp_status, 200))
{
// Session has been set up successfully.
TRC_DEBUG("Session successful");
_icscf->_session_establishment_tbl->increment_successes();
_icscf->_session_establishment_network_tbl->increment_successes();
}
else if ((rsp_status == PJSIP_SC_BUSY_HERE) ||
(rsp_status == PJSIP_SC_BUSY_EVERYWHERE) ||
(rsp_status == PJSIP_SC_NOT_FOUND) ||
(rsp_status == PJSIP_SC_ADDRESS_INCOMPLETE))
{
// Session failed, but should be counted as successful from a network
// perspective.
TRC_DEBUG("Session failed but network successful");
_icscf->_session_establishment_tbl->increment_failures();
_icscf->_session_establishment_network_tbl->increment_successes();
}
else
{
// Session establishment failed.
TRC_DEBUG("Session failed");
_icscf->_session_establishment_tbl->increment_failures();
_icscf->_session_establishment_network_tbl->increment_failures();
}
}
}

}


Expand Down
Loading