summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2006-06-13 22:21:23 +0000
committerBenny Prijono <bennylp@teluu.com>2006-06-13 22:21:23 +0000
commit26af83c5f17911357c683761253a7b25993f321f (patch)
tree5a206ec979fbf063bd4bc0ebd4294c754d9738ac
parentf0bcd9121b3833df88a00d7808fc578c1bced67e (diff)
Added status_text and cause_text in dialog and transaction to capture the real status text in the final response (instead of just the code)
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@500 74dad513-b988-da41-8d7b-12977e46ad98
-rw-r--r--pjsip/include/pjsip-ua/sip_inv.h3
-rw-r--r--pjsip/include/pjsip/sip_transaction.h1
-rw-r--r--pjsip/src/pjsip-ua/sip_inv.c57
-rw-r--r--pjsip/src/pjsip/sip_transaction.c54
4 files changed, 80 insertions, 35 deletions
diff --git a/pjsip/include/pjsip-ua/sip_inv.h b/pjsip/include/pjsip-ua/sip_inv.h
index c85795ab..cdc8b8f9 100644
--- a/pjsip/include/pjsip-ua/sip_inv.h
+++ b/pjsip/include/pjsip-ua/sip_inv.h
@@ -166,10 +166,11 @@ enum pjsip_inv_option
*/
struct pjsip_inv_session
{
- char obj_name[PJ_MAX_OBJ_NAME]; /**< Log identification. */
+ char obj_name[PJ_MAX_OBJ_NAME]; /**< Log identification */
pj_pool_t *pool; /**< Dialog's pool. */
pjsip_inv_state state; /**< Invite sess state. */
pjsip_status_code cause; /**< Disconnect cause. */
+ pj_str_t cause_text; /**< Cause text. */
pj_bool_t notify; /**< Internal. */
pjsip_dialog *dlg; /**< Underlying dialog. */
pjsip_role_e role; /**< Invite role. */
diff --git a/pjsip/include/pjsip/sip_transaction.h b/pjsip/include/pjsip/sip_transaction.h
index 7878ec66..895487dd 100644
--- a/pjsip/include/pjsip/sip_transaction.h
+++ b/pjsip/include/pjsip/sip_transaction.h
@@ -82,6 +82,7 @@ struct pjsip_transaction
* State and status.
*/
int status_code; /**< Last status code seen. */
+ pj_str_t status_text; /**< Last reason phrase. */
pjsip_tsx_state_e state; /**< State. */
int handle_200resp; /**< UAS 200/INVITE retrsm.*/
int tracing; /**< Tracing enabled? */
diff --git a/pjsip/src/pjsip-ua/sip_inv.c b/pjsip/src/pjsip-ua/sip_inv.c
index 593a914e..4efb9177 100644
--- a/pjsip/src/pjsip-ua/sip_inv.c
+++ b/pjsip/src/pjsip-ua/sip_inv.c
@@ -158,6 +158,25 @@ void inv_set_state(pjsip_inv_session *inv, pjsip_inv_state state,
/*
+ * Set cause code.
+ */
+void inv_set_cause(pjsip_inv_session *inv, int cause_code,
+ const pj_str_t *cause_text)
+{
+ if (cause_code > inv->cause) {
+ inv->cause = cause_code;
+ if (cause_text)
+ pj_strdup(inv->pool, &inv->cause_text, cause_text);
+ else if (cause_code/100 == 2)
+ inv->cause_text = pj_str("Normal call clearing");
+ else
+ inv->cause_text = *pjsip_get_status_text(cause_code);
+ }
+}
+
+
+
+/*
* Send ACK for 2xx response.
*/
static pj_status_t inv_send_ack(pjsip_inv_session *inv, pjsip_rx_data *rdata)
@@ -898,7 +917,7 @@ PJ_DEF(pj_status_t) pjsip_inv_terminate( pjsip_inv_session *inv,
}
/* Set cause. */
- inv->cause = st_code;
+ inv_set_cause(inv, st_code, NULL);
/* Forcefully terminate the session if state is not DISCONNECTED */
if (inv->state != PJSIP_INV_STATE_DISCONNECTED) {
@@ -1387,7 +1406,7 @@ PJ_DEF(pj_status_t) pjsip_inv_end_session( pjsip_inv_session *inv,
PJ_ASSERT_RETURN(inv && p_tdata, PJ_EINVAL);
/* Set cause code. */
- if (inv->cause==0) inv->cause = st_code;
+ inv_set_cause(inv, st_code, st_text);
/* Create appropriate message. */
switch (inv->state) {
@@ -1697,7 +1716,7 @@ static void inv_respond_incoming_bye( pjsip_inv_session *inv,
/* Terminate session: */
if (inv->state != PJSIP_INV_STATE_DISCONNECTED) {
- if (inv->cause==0) inv->cause=PJSIP_SC_OK;
+ inv_set_cause(inv, PJSIP_SC_OK, NULL);
inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e);
}
}
@@ -1713,7 +1732,7 @@ static void inv_handle_bye_response( pjsip_inv_session *inv,
pj_status_t status;
if (e->body.tsx_state.type != PJSIP_EVENT_RX_MSG) {
- if (inv->cause==0) inv->cause=PJSIP_SC_OK;
+ inv_set_cause(inv, PJSIP_SC_OK, NULL);
inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e);
return;
}
@@ -1733,7 +1752,7 @@ static void inv_handle_bye_response( pjsip_inv_session *inv,
/* Does not have proper credentials.
* End the session anyway.
*/
- if (inv->cause==0) inv->cause=PJSIP_SC_OK;
+ inv_set_cause(inv, PJSIP_SC_OK, NULL);
inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e);
} else {
@@ -1744,7 +1763,7 @@ static void inv_handle_bye_response( pjsip_inv_session *inv,
} else {
/* End the session. */
- if (inv->cause==0) inv->cause=PJSIP_SC_OK;
+ inv_set_cause(inv, PJSIP_SC_OK, NULL);
inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e);
}
@@ -1862,7 +1881,7 @@ static void inv_on_state_calling( pjsip_inv_session *inv, pjsip_event *e)
/* Does not have proper credentials.
* End the session.
*/
- if (inv->cause==0) inv->cause = tsx->status_code;
+ inv_set_cause(inv, tsx->status_code, &tsx->status_text);
inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e);
} else {
@@ -1877,7 +1896,7 @@ static void inv_on_state_calling( pjsip_inv_session *inv, pjsip_event *e)
} else {
- if (inv->cause==0) inv->cause = tsx->status_code;
+ inv_set_cause(inv, tsx->status_code, &tsx->status_text);
inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e);
}
@@ -1905,7 +1924,7 @@ static void inv_on_state_calling( pjsip_inv_session *inv, pjsip_event *e)
} else {
- if (inv->cause==0) inv->cause = tsx->status_code;
+ inv_set_cause(inv, tsx->status_code, &tsx->status_text);
inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e);
}
break;
@@ -1926,9 +1945,9 @@ static void inv_on_state_calling( pjsip_inv_session *inv, pjsip_event *e)
if (tsx->status_code == PJSIP_SC_CALL_TSX_DOES_NOT_EXIST ||
tsx->status_code == PJSIP_SC_REQUEST_TIMEOUT ||
tsx->status_code == PJSIP_SC_TSX_TIMEOUT ||
- PJSIP_SC_TSX_TRANSPORT_ERROR)
+ tsx->status_code == PJSIP_SC_TSX_TRANSPORT_ERROR)
{
- if (inv->cause==0) inv->cause = tsx->status_code;
+ inv_set_cause(inv, tsx->status_code, &tsx->status_text);
inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e);
}
}
@@ -1972,7 +1991,7 @@ static void inv_on_state_incoming( pjsip_inv_session *inv, pjsip_event *e)
if (tsx->status_code/100 == 2) {
inv_set_state(inv, PJSIP_INV_STATE_CONNECTING, e);
} else {
- if (inv->cause==0) inv->cause = tsx->status_code;
+ inv_set_cause(inv, tsx->status_code, &tsx->status_text);
inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e);
}
break;
@@ -1982,7 +2001,7 @@ static void inv_on_state_incoming( pjsip_inv_session *inv, pjsip_event *e)
* This happens on transport error (e.g. failed to send
* response)
*/
- if (inv->cause==0) inv->cause = tsx->status_code;
+ inv_set_cause(inv, tsx->status_code, &tsx->status_text);
inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e);
break;
@@ -2044,7 +2063,7 @@ static void inv_on_state_early( pjsip_inv_session *inv, pjsip_event *e)
}
} else {
- if (inv->cause==0) inv->cause = tsx->status_code;
+ inv_set_cause(inv, tsx->status_code, &tsx->status_text);
inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e);
}
break;
@@ -2078,7 +2097,7 @@ static void inv_on_state_early( pjsip_inv_session *inv, pjsip_event *e)
}
} else {
- if (inv->cause==0) inv->cause = tsx->status_code;
+ inv_set_cause(inv, tsx->status_code, &tsx->status_text);
inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e);
}
break;
@@ -2112,9 +2131,9 @@ static void inv_on_state_early( pjsip_inv_session *inv, pjsip_event *e)
if (tsx->status_code == PJSIP_SC_CALL_TSX_DOES_NOT_EXIST ||
tsx->status_code == PJSIP_SC_REQUEST_TIMEOUT ||
tsx->status_code == PJSIP_SC_TSX_TIMEOUT ||
- PJSIP_SC_TSX_TRANSPORT_ERROR)
+ tsx->status_code == PJSIP_SC_TSX_TRANSPORT_ERROR)
{
- if (inv->cause==0) inv->cause = tsx->status_code;
+ inv_set_cause(inv, tsx->status_code, &tsx->status_text);
inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e);
}
}
@@ -2148,7 +2167,7 @@ static void inv_on_state_connecting( pjsip_inv_session *inv, pjsip_event *e)
* error.
*/
if (tsx->status_code/100 != 2) {
- if (inv->cause==0) inv->cause = tsx->status_code;
+ inv_set_cause(inv, tsx->status_code, &tsx->status_text);
inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e);
}
break;
@@ -2340,7 +2359,7 @@ static void inv_on_state_confirmed( pjsip_inv_session *inv, pjsip_event *e)
/*
* Handle responses that terminates dialog.
*/
- if (inv->cause==0) inv->cause = tsx->status_code;
+ inv_set_cause(inv, tsx->status_code, &tsx->status_text);
inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e);
}
}
diff --git a/pjsip/src/pjsip/sip_transaction.c b/pjsip/src/pjsip/sip_transaction.c
index 8fe2a23a..efbac0a7 100644
--- a/pjsip/src/pjsip/sip_transaction.c
+++ b/pjsip/src/pjsip/sip_transaction.c
@@ -1326,6 +1326,20 @@ PJ_DEF(pj_status_t) pjsip_tsx_create_uas( pjsip_module *tsx_user,
/*
+ * Set transaction status code and reason.
+ */
+static tsx_set_status_code(pjsip_transaction *tsx,
+ int code, const pj_str_t *reason)
+{
+ tsx->status_code = code;
+ if (reason)
+ pj_strdup(tsx->pool, &tsx->status_text, reason);
+ else
+ tsx->status_text = *pjsip_get_status_text(code);
+}
+
+
+/*
* Forcely terminate transaction.
*/
PJ_DEF(pj_status_t) pjsip_tsx_terminate( pjsip_transaction *tsx, int code )
@@ -1341,7 +1355,7 @@ PJ_DEF(pj_status_t) pjsip_tsx_terminate( pjsip_transaction *tsx, int code )
return PJ_SUCCESS;
lock_tsx(tsx, &lck);
- tsx->status_code = code;
+ tsx_set_status_code(tsx, code, NULL);
tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED, PJSIP_EVENT_USER, NULL);
unlock_tsx(tsx, &lck);
@@ -1491,13 +1505,16 @@ static void send_msg_callback( pjsip_send_state *send_state,
if (!*cont) {
char errmsg[PJ_ERR_MSG_SIZE];
+ pj_str_t err;
tsx->transport_err = -sent;
+ err =pj_strerror(-sent, errmsg, sizeof(errmsg));
+
PJ_LOG(4,(tsx->obj_name,
"Failed to send %s! err=%d (%s)",
pjsip_tx_data_get_info(send_state->tdata), -sent,
- pj_strerror(-sent, errmsg, sizeof(errmsg)).ptr));
+ errmsg));
/* Clear pending transport flag. */
tsx->transport_flag &= ~(TSX_HAS_PENDING_TRANSPORT);
@@ -1506,7 +1523,7 @@ static void send_msg_callback( pjsip_send_state *send_state,
tsx->transport_flag |= TSX_HAS_RESOLVED_SERVER;
/* Terminate transaction, if it's not already terminated. */
- tsx->status_code = PJSIP_SC_TSX_TRANSPORT_ERROR;
+ tsx_set_status_code(tsx, PJSIP_SC_TSX_TRANSPORT_ERROR, &err);
if (tsx->state != PJSIP_TSX_STATE_TERMINATED &&
tsx->state != PJSIP_TSX_STATE_DESTROYED)
{
@@ -1537,12 +1554,14 @@ static void transport_callback(void *token, pjsip_tx_data *tdata,
pjsip_transaction *tsx = token;
struct tsx_lock_data lck;
char errmsg[PJ_ERR_MSG_SIZE];
+ pj_str_t err;
tsx->transport_err = -sent;
+ err = pj_strerror(-sent, errmsg, sizeof(errmsg));
+
PJ_LOG(4,(tsx->obj_name, "Transport failed to send %s! Err=%d (%s)",
- pjsip_tx_data_get_info(tdata), -sent,
- pj_strerror(-sent, errmsg, sizeof(errmsg)).ptr));
+ pjsip_tx_data_get_info(tdata), -sent, errmsg));
lock_tsx(tsx, &lck);
@@ -1551,7 +1570,7 @@ static void transport_callback(void *token, pjsip_tx_data *tdata,
tsx->transport = NULL;
/* Terminate transaction. */
- tsx->status_code = PJSIP_SC_TSX_TRANSPORT_ERROR;
+ tsx_set_status_code(tsx, PJSIP_SC_TSX_TRANSPORT_ERROR, &err);
tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED,
PJSIP_EVENT_TRANSPORT_ERROR, tdata );
@@ -1621,6 +1640,7 @@ static pj_status_t tsx_send_msg( pjsip_transaction *tsx,
if (tsx->transport_flag & TSX_HAS_RESOLVED_SERVER) {
char errmsg[PJ_ERR_MSG_SIZE];
+ pj_str_t err;
if (status == PJ_SUCCESS) {
pj_assert(!"Unexpected status!");
@@ -1630,13 +1650,14 @@ static pj_status_t tsx_send_msg( pjsip_transaction *tsx,
/* We have resolved the server!.
* Treat this as permanent transport error.
*/
+ err = pj_strerror(status, errmsg, sizeof(errmsg));
+
PJ_LOG(4,(tsx->obj_name,
"Transport error, terminating transaction. "
"Err=%d (%s)",
- status,
- pj_strerror(status, errmsg, sizeof(errmsg)).ptr));
+ status, errmsg));
- tsx->status_code = PJSIP_SC_TSX_TRANSPORT_ERROR;
+ tsx_set_status_code(tsx, PJSIP_SC_TSX_TRANSPORT_ERROR, &err);
tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED,
PJSIP_EVENT_TRANSPORT_ERROR, NULL );
@@ -1859,7 +1880,7 @@ static pj_status_t tsx_on_state_calling( pjsip_transaction *tsx,
tsx->transport_flag &= ~(TSX_HAS_PENDING_RESCHED);
/* Set status code */
- tsx->status_code = PJSIP_SC_TSX_TIMEOUT;
+ tsx_set_status_code(tsx, PJSIP_SC_TSX_TIMEOUT, NULL);
/* Inform TU. */
tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED,
@@ -2001,7 +2022,8 @@ static pj_status_t tsx_on_state_proceeding_uas( pjsip_transaction *tsx,
PJ_ASSERT_RETURN(msg->type==PJSIP_RESPONSE_MSG, PJSIP_ENOTRESPONSEMSG);
/* Update last status */
- tsx->status_code = msg->line.status.code;
+ tsx_set_status_code(tsx, msg->line.status.code,
+ &msg->line.status.reason);
/* Discard the saved last response (it will be updated later as
* necessary).
@@ -2163,7 +2185,7 @@ static pj_status_t tsx_on_state_proceeding_uas( pjsip_transaction *tsx,
/* Timeout timer. should not happen? */
pj_assert(!"Should not happen(?)");
- tsx->status_code = PJSIP_SC_TSX_TIMEOUT;
+ tsx_set_status_code(tsx, PJSIP_SC_TSX_TIMEOUT, NULL);
tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED,
PJSIP_EVENT_TIMER, &tsx->timeout_timer);
@@ -2210,9 +2232,11 @@ static pj_status_t tsx_on_state_proceeding_uac(pjsip_transaction *tsx,
return PJSIP_ENOTRESPONSEMSG;
}
- tsx->status_code = msg->line.status.code;
+ tsx_set_status_code(tsx, msg->line.status.code,
+ &msg->line.status.reason);
+
} else {
- tsx->status_code = PJSIP_SC_TSX_TIMEOUT;
+ tsx_set_status_code(tsx, PJSIP_SC_TSX_TIMEOUT, NULL);
}
if (PJSIP_IS_STATUS_IN_CLASS(tsx->status_code, 100)) {
@@ -2440,7 +2464,7 @@ static pj_status_t tsx_on_state_completed_uas( pjsip_transaction *tsx,
* Set state to Terminated, and inform TU.
*/
- tsx->status_code = PJSIP_SC_TSX_TIMEOUT;
+ tsx_set_status_code(tsx, PJSIP_SC_TSX_TIMEOUT, NULL);
tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED,
PJSIP_EVENT_TIMER, &tsx->timeout_timer );