diff options
-rw-r--r-- | pjsip/include/pjsip-ua/sip_inv.h | 3 | ||||
-rw-r--r-- | pjsip/include/pjsip/sip_transaction.h | 1 | ||||
-rw-r--r-- | pjsip/src/pjsip-ua/sip_inv.c | 57 | ||||
-rw-r--r-- | pjsip/src/pjsip/sip_transaction.c | 54 |
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 ); |