summaryrefslogtreecommitdiff
path: root/pjsip/src/pjsip-ua/sip_inv.c
diff options
context:
space:
mode:
Diffstat (limited to 'pjsip/src/pjsip-ua/sip_inv.c')
-rw-r--r--pjsip/src/pjsip-ua/sip_inv.c129
1 files changed, 109 insertions, 20 deletions
diff --git a/pjsip/src/pjsip-ua/sip_inv.c b/pjsip/src/pjsip-ua/sip_inv.c
index ae1011ef..80ae9718 100644
--- a/pjsip/src/pjsip-ua/sip_inv.c
+++ b/pjsip/src/pjsip-ua/sip_inv.c
@@ -19,6 +19,7 @@
*/
#include <pjsip-ua/sip_inv.h>
#include <pjsip-ua/sip_100rel.h>
+#include <pjsip-ua/sip_timer.h>
#include <pjsip/sip_module.h>
#include <pjsip/sip_endpoint.h>
#include <pjsip/sip_event.h>
@@ -231,6 +232,7 @@ void inv_set_state(pjsip_inv_session *inv, pjsip_inv_state state,
inv->invite_req = NULL;
}
pjsip_100rel_end_session(inv);
+ pjsip_timer_end_session(inv);
pjsip_dlg_dec_session(inv->dlg, &mod_inv.mod);
}
}
@@ -481,6 +483,7 @@ static pj_bool_t mod_inv_on_rx_response(pjsip_rx_data *rdata)
pjsip_dialog *dlg;
pjsip_inv_session *inv;
pjsip_msg *msg = rdata->msg_info.msg;
+ pj_status_t status;
dlg = pjsip_rdata_get_dlg(rdata);
@@ -508,6 +511,23 @@ static pj_bool_t mod_inv_on_rx_response(pjsip_rx_data *rdata)
}
+ /* Pass response to timer session module */
+ status = pjsip_timer_process_resp(inv, rdata);
+ if (status != PJ_SUCCESS) {
+ pjsip_event e;
+ pjsip_tx_data *tdata;
+
+ PJSIP_EVENT_INIT_RX_MSG(e, rdata);
+ inv_send_ack(inv, &e);
+
+ status = pjsip_inv_end_session(inv, PJSIP_ERRNO_TO_SIP_STATUS(status),
+ NULL, &tdata);
+ if (tdata && status == PJ_SUCCESS)
+ pjsip_inv_send_msg(inv, tdata);
+
+ return PJ_TRUE;
+ }
+
/* No other processing needs to be done here. */
return PJ_FALSE;
}
@@ -634,7 +654,6 @@ PJ_DEF(pj_status_t) pjsip_inv_create_uac( pjsip_dialog *dlg,
/* Normalize options */
if (options & PJSIP_INV_REQUIRE_100REL)
options |= PJSIP_INV_SUPPORT_100REL;
-
if (options & PJSIP_INV_REQUIRE_TIMER)
options |= PJSIP_INV_SUPPORT_TIMER;
@@ -716,7 +735,6 @@ PJ_DEF(pj_status_t) pjsip_inv_verify_request2(pjsip_rx_data *rdata,
/* Normalize options */
if (*options & PJSIP_INV_REQUIRE_100REL)
*options |= PJSIP_INV_SUPPORT_100REL;
-
if (*options & PJSIP_INV_REQUIRE_TIMER)
*options |= PJSIP_INV_SUPPORT_TIMER;
@@ -867,13 +885,13 @@ PJ_DEF(pj_status_t) pjsip_inv_verify_request2(pjsip_rx_data *rdata,
pjsip_msg_find_hdr(msg, PJSIP_H_SUPPORTED, NULL);
if (sup_hdr) {
unsigned i;
- pj_str_t STR_100REL = { "100rel", 6};
- pj_str_t STR_TIMER = { "timer", 5 };
+ const pj_str_t STR_100REL = { "100rel", 6};
+ const pj_str_t STR_TIMER = { "timer", 5};
for (i=0; i<sup_hdr->count; ++i) {
if (pj_stricmp(&sup_hdr->values[i], &STR_100REL)==0)
rem_option |= PJSIP_INV_SUPPORT_100REL;
- else if (pj_stricmp(&sup_hdr->values[i], &STR_TIMER)==0)
+ if (pj_stricmp(&sup_hdr->values[i], &STR_TIMER)==0)
rem_option |= PJSIP_INV_SUPPORT_TIMER;
}
}
@@ -884,8 +902,8 @@ PJ_DEF(pj_status_t) pjsip_inv_verify_request2(pjsip_rx_data *rdata,
if (req_hdr) {
unsigned i;
const pj_str_t STR_100REL = { "100rel", 6};
- const pj_str_t STR_TIMER = { "timer", 5 };
const pj_str_t STR_REPLACES = { "replaces", 8 };
+ const pj_str_t STR_TIMER = { "timer", 5 };
unsigned unsupp_cnt = 0;
pj_str_t unsupp_tags[PJSIP_GENERIC_ARRAY_MAX_COUNT];
@@ -895,8 +913,8 @@ PJ_DEF(pj_status_t) pjsip_inv_verify_request2(pjsip_rx_data *rdata,
{
rem_option |= PJSIP_INV_REQUIRE_100REL;
- } else if ((*options && PJSIP_INV_SUPPORT_TIMER) &&
- pj_stricmp(&req_hdr->values[i], &STR_TIMER)==0)
+ } else if ((*options & PJSIP_INV_SUPPORT_TIMER) &&
+ pj_stricmp(&req_hdr->values[i], &STR_TIMER)==0)
{
rem_option |= PJSIP_INV_REQUIRE_TIMER;
@@ -956,8 +974,8 @@ PJ_DEF(pj_status_t) pjsip_inv_verify_request2(pjsip_rx_data *rdata,
*/
if ( ((*options & PJSIP_INV_REQUIRE_100REL)!=0 &&
(rem_option & PJSIP_INV_SUPPORT_100REL)==0) ||
- ((*options & PJSIP_INV_REQUIRE_TIMER)!=0 &&
- (rem_option & PJSIP_INV_SUPPORT_TIMER)==0))
+ ((*options & PJSIP_INV_REQUIRE_100REL)!=0 &&
+ (rem_option & PJSIP_INV_SUPPORT_100REL)==0))
{
code = PJSIP_SC_EXTENSION_REQUIRED;
status = PJSIP_ERRNO_FROM_SIP_STATUS(code);
@@ -971,7 +989,6 @@ PJ_DEF(pj_status_t) pjsip_inv_verify_request2(pjsip_rx_data *rdata,
if (*options & PJSIP_INV_REQUIRE_100REL)
req_hdr->values[req_hdr->count++] = pj_str("100rel");
-
if (*options & PJSIP_INV_REQUIRE_TIMER)
req_hdr->values[req_hdr->count++] = pj_str("timer");
@@ -1097,7 +1114,6 @@ PJ_DEF(pj_status_t) pjsip_inv_create_uas( pjsip_dialog *dlg,
/* Normalize options */
if (options & PJSIP_INV_REQUIRE_100REL)
options |= PJSIP_INV_SUPPORT_100REL;
-
if (options & PJSIP_INV_REQUIRE_TIMER)
options |= PJSIP_INV_SUPPORT_TIMER;
@@ -1169,7 +1185,7 @@ PJ_DEF(pj_status_t) pjsip_inv_create_uas( pjsip_dialog *dlg,
/* Create 100rel handler */
if (inv->options & PJSIP_INV_REQUIRE_100REL) {
- pjsip_100rel_attach(inv);
+ pjsip_100rel_attach(inv);
}
/* Done */
@@ -1394,16 +1410,25 @@ PJ_DEF(pj_status_t) pjsip_inv_invite( pjsip_inv_session *inv,
}
/* Add Require header. */
- if (inv->options & PJSIP_INV_REQUIRE_100REL) {
- const pj_str_t HREQ = { "Require", 7 };
- const pj_str_t tag_100rel = { "100rel", 6 };
- pjsip_generic_string_hdr *hreq;
+ if ((inv->options & PJSIP_INV_REQUIRE_100REL) ||
+ (inv->options & PJSIP_INV_REQUIRE_TIMER))
+ {
+ pjsip_require_hdr *hreq;
+
+ hreq = pjsip_require_hdr_create(tdata->pool);
- hreq = pjsip_generic_string_hdr_create(tdata->pool, &HREQ,
- &tag_100rel);
- pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*) hreq);
+ if (inv->options & PJSIP_INV_REQUIRE_100REL)
+ hreq->values[hreq->count++] = pj_str("100rel");
+ if (inv->options & PJSIP_INV_REQUIRE_TIMER)
+ hreq->values[hreq->count++] = pj_str("timer");
+
+ pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*) hreq);
}
+ status = pjsip_timer_update_req(inv, tdata);
+ if (status != PJ_SUCCESS)
+ goto on_return;
+
/* Done. */
*p_tdata = tdata;
@@ -1745,6 +1770,27 @@ PJ_DEF(pj_status_t) pjsip_inv_initial_answer( pjsip_inv_session *inv,
if (status != PJ_SUCCESS)
goto on_return;
+ /* Invoke Session Timers module */
+ status = pjsip_timer_process_req(inv, rdata);
+ if (status != PJ_SUCCESS) {
+ pj_status_t status2;
+
+ status2 = pjsip_dlg_modify_response(inv->dlg, tdata,
+ PJSIP_ERRNO_TO_SIP_STATUS(status),
+ NULL);
+ if (status2 != PJ_SUCCESS) {
+ pjsip_tx_data_dec_ref(tdata);
+ goto on_return;
+ }
+ status2 = pjsip_timer_update_resp(inv, tdata);
+ if (status2 == PJ_SUCCESS)
+ *p_tdata = tdata;
+ else
+ pjsip_tx_data_dec_ref(tdata);
+
+ goto on_return;
+ }
+
/* Process SDP in answer */
status = process_answer(inv, st_code, tdata, sdp);
if (status != PJ_SUCCESS) {
@@ -1758,6 +1804,9 @@ PJ_DEF(pj_status_t) pjsip_inv_initial_answer( pjsip_inv_session *inv,
PJ_LOG(5,(inv->dlg->obj_name, "Initial answer %s",
pjsip_tx_data_get_info(inv->last_answer)));
+ /* Invoke Session Timers */
+ pjsip_timer_update_resp(inv, tdata);
+
*p_tdata = tdata;
on_return:
@@ -1808,6 +1857,8 @@ PJ_DEF(pj_status_t) pjsip_inv_answer( pjsip_inv_session *inv,
goto on_return;
}
+ /* Invoke Session Timers */
+ pjsip_timer_update_resp(inv, last_res);
*p_tdata = last_res;
@@ -1912,6 +1963,9 @@ PJ_DEF(pj_status_t) pjsip_inv_end_session( pjsip_inv_session *inv,
case PJSIP_INV_STATE_CONNECTING:
case PJSIP_INV_STATE_CONFIRMED:
+ /* End Session Timer */
+ pjsip_timer_end_session(inv);
+
/* For established dialog, send BYE */
status = pjsip_dlg_create_request(inv->dlg, pjsip_get_bye_method(),
-1, &tdata);
@@ -2300,6 +2354,10 @@ PJ_DEF(pj_status_t) pjsip_inv_update ( pjsip_inv_session *inv,
/* Unlock dialog. */
pjsip_dlg_dec_lock(inv->dlg);
+ status = pjsip_timer_update_req(inv, tdata);
+ if (status != PJ_SUCCESS)
+ goto on_error;
+
*p_tdata = tdata;
return PJ_SUCCESS;
@@ -2581,6 +2639,15 @@ static void inv_respond_incoming_update(pjsip_inv_session *inv,
pj_status_t status;
pjsip_tx_data *tdata = NULL;
+ /* Invoke Session Timers module */
+ status = pjsip_timer_process_req(inv, rdata);
+ if (status != PJ_SUCCESS) {
+ status = pjsip_dlg_create_response(inv->dlg, rdata,
+ PJSIP_ERRNO_TO_SIP_STATUS(status),
+ NULL, &tdata);
+ goto on_return;
+ }
+
neg_state = pjmedia_sdp_neg_get_state(inv->neg);
/* Send 491 if we receive UPDATE while we're waiting for an answer */
@@ -2634,6 +2701,11 @@ static void inv_respond_incoming_update(pjsip_inv_session *inv,
}
}
+on_return:
+ /* Invoke Session Timers */
+ if (status == PJ_SUCCESS)
+ status = pjsip_timer_update_resp(inv, tdata);
+
if (status != PJ_SUCCESS) {
if (tdata != NULL) {
pjsip_tx_data_dec_ref(tdata);
@@ -3609,6 +3681,20 @@ static void inv_on_state_confirmed( pjsip_inv_session *inv, pjsip_event *e)
/* Save the invite transaction. */
inv->invite_tsx = tsx;
+ /* Process session timers headers in the re-INVITE */
+ status = pjsip_timer_process_req(inv, rdata);
+ if (status != PJ_SUCCESS) {
+ status = pjsip_dlg_create_response(inv->dlg, rdata,
+ PJSIP_ERRNO_TO_SIP_STATUS(status),
+ NULL, &tdata);
+ if (status != PJ_SUCCESS)
+ return;
+
+ pjsip_timer_update_resp(inv, tdata);
+ status = pjsip_dlg_send_response(dlg, tsx, tdata);
+ return;
+ }
+
/* Process SDP in incoming message. */
status = inv_check_sdp_in_incoming_msg(inv, tsx, rdata);
@@ -3716,6 +3802,9 @@ static void inv_on_state_confirmed( pjsip_inv_session *inv, pjsip_event *e)
return;
}
+ /* Invoke Session Timers */
+ pjsip_timer_update_resp(inv, tdata);
+
/* Send 2xx regardless of the status of negotiation */
status = pjsip_inv_send_msg(inv, tdata);