Fixed ticket #89: implement transaction timeout in REGISTER request (thanks Frank Wiersma for reporting the problem)
git-svn-id: https://svn.pjsip.org/repos/pjproject/trunk@932 74dad513-b988-da41-8d7b-12977e46ad98
This commit is contained in:
parent
400e58c295
commit
0f35f91aec
|
@ -426,6 +426,7 @@ PJ_DECL(pj_status_t) pjsip_endpt_respond( pjsip_endpoint *endpt,
|
|||
* @param tdata The transmit data to be sent.
|
||||
* @param timeout Optional timeout for final response to be received, or -1
|
||||
* if the transaction should not have a timeout restriction.
|
||||
* The value is in miliseconds.
|
||||
* @param token Optional token to be associated with the transaction, and
|
||||
* to be passed to the callback.
|
||||
* @param cb Optional callback to be called when the transaction has
|
||||
|
@ -437,7 +438,7 @@ PJ_DECL(pj_status_t) pjsip_endpt_respond( pjsip_endpoint *endpt,
|
|||
*/
|
||||
PJ_DECL(pj_status_t) pjsip_endpt_send_request( pjsip_endpoint *endpt,
|
||||
pjsip_tx_data *tdata,
|
||||
int timeout,
|
||||
pj_int32_t timeout,
|
||||
void *token,
|
||||
void (*cb)(void*,pjsip_event*));
|
||||
|
||||
|
|
|
@ -38,6 +38,12 @@
|
|||
#define DELAY_BEFORE_REFRESH 5
|
||||
#define THIS_FILE "sip_regc.c"
|
||||
|
||||
/* Outgoing transaction timeout when server sends 100 but never replies
|
||||
* with final response. Value is in MILISECONDS!
|
||||
*/
|
||||
#define REGC_TSX_TIMEOUT 33000
|
||||
|
||||
|
||||
/**
|
||||
* SIP client registration structure.
|
||||
*/
|
||||
|
@ -742,7 +748,8 @@ PJ_DEF(pj_status_t) pjsip_regc_send(pjsip_regc *regc, pjsip_tx_data *tdata)
|
|||
*/
|
||||
regc->has_tsx = PJ_TRUE;
|
||||
++regc->busy;
|
||||
status = pjsip_endpt_send_request(regc->endpt, tdata, -1, regc, &tsx_callback);
|
||||
status = pjsip_endpt_send_request(regc->endpt, tdata, REGC_TSX_TIMEOUT,
|
||||
regc, &tsx_callback);
|
||||
if (status!=PJ_SUCCESS) {
|
||||
PJ_LOG(4,(THIS_FILE, "Error sending request, status=%d", status));
|
||||
}
|
||||
|
|
|
@ -22,11 +22,16 @@
|
|||
#include <pjsip/sip_transaction.h>
|
||||
#include <pjsip/sip_event.h>
|
||||
#include <pjsip/sip_errno.h>
|
||||
#include <pj/pool.h>
|
||||
#include <pj/assert.h>
|
||||
#include <pj/log.h>
|
||||
#include <pj/pool.h>
|
||||
#include <pj/string.h>
|
||||
|
||||
struct tsx_data
|
||||
{
|
||||
pj_time_val delay;
|
||||
pj_timer_entry timeout_timer;
|
||||
|
||||
void *token;
|
||||
void (*cb)(void*, pjsip_event*);
|
||||
};
|
||||
|
@ -66,6 +71,12 @@ static void mod_util_on_tsx_state(pjsip_transaction *tsx, pjsip_event *event)
|
|||
if (tsx->status_code < 200)
|
||||
return;
|
||||
|
||||
/* Cancel timer if any */
|
||||
if (tsx_data->timeout_timer.id != 0) {
|
||||
tsx_data->timeout_timer.id = 0;
|
||||
pjsip_endpt_cancel_timer(tsx->endpt, &tsx_data->timeout_timer);
|
||||
}
|
||||
|
||||
/* Call the callback, if any, and prevent the callback to be called again
|
||||
* by clearing the transaction's module_data.
|
||||
*/
|
||||
|
@ -77,9 +88,32 @@ static void mod_util_on_tsx_state(pjsip_transaction *tsx, pjsip_event *event)
|
|||
}
|
||||
|
||||
|
||||
static void mod_util_on_timeout(pj_timer_heap_t *th, pj_timer_entry *te)
|
||||
{
|
||||
pjsip_transaction *tsx = (pjsip_transaction*) te->user_data;
|
||||
struct tsx_data *tsx_data;
|
||||
|
||||
PJ_UNUSED_ARG(th);
|
||||
|
||||
tsx_data = tsx->mod_data[mod_stateful_util.id];
|
||||
if (tsx_data == NULL) {
|
||||
pj_assert(!"Shouldn't happen");
|
||||
return;
|
||||
}
|
||||
|
||||
tsx_data->timeout_timer.id = 0;
|
||||
|
||||
PJ_LOG(4,(tsx->obj_name, "Transaction timed out by user timer (%d.%d sec)",
|
||||
(int)tsx_data->delay.sec, (int)tsx_data->delay.msec));
|
||||
|
||||
/* Terminate the transaction. This will call mod_util_on_tsx_state() */
|
||||
pjsip_tsx_terminate(tsx, PJSIP_SC_TSX_TIMEOUT);
|
||||
}
|
||||
|
||||
|
||||
PJ_DEF(pj_status_t) pjsip_endpt_send_request( pjsip_endpoint *endpt,
|
||||
pjsip_tx_data *tdata,
|
||||
int timeout,
|
||||
pj_int32_t timeout,
|
||||
void *token,
|
||||
void (*cb)(void*,pjsip_event*))
|
||||
{
|
||||
|
@ -99,16 +133,38 @@ PJ_DEF(pj_status_t) pjsip_endpt_send_request( pjsip_endpoint *endpt,
|
|||
return status;
|
||||
}
|
||||
|
||||
tsx_data = pj_pool_alloc(tsx->pool, sizeof(struct tsx_data));
|
||||
tsx_data = pj_pool_zalloc(tsx->pool, sizeof(struct tsx_data));
|
||||
tsx_data->token = token;
|
||||
tsx_data->cb = cb;
|
||||
|
||||
if (timeout >= 0) {
|
||||
tsx_data->delay.sec = 0;
|
||||
tsx_data->delay.msec = timeout;
|
||||
pj_time_val_normalize(&tsx_data->delay);
|
||||
|
||||
tsx_data->timeout_timer.id = PJ_TRUE;
|
||||
tsx_data->timeout_timer.user_data = tsx;
|
||||
tsx_data->timeout_timer.cb = &mod_util_on_timeout;
|
||||
|
||||
status = pjsip_endpt_schedule_timer(endpt, &tsx_data->timeout_timer,
|
||||
&tsx_data->delay);
|
||||
if (status != PJ_SUCCESS) {
|
||||
pjsip_tsx_terminate(tsx, PJSIP_SC_INTERNAL_SERVER_ERROR);
|
||||
pjsip_tx_data_dec_ref(tdata);
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
tsx->mod_data[mod_stateful_util.id] = tsx_data;
|
||||
|
||||
PJ_TODO(IMPLEMENT_TIMEOUT_FOR_SEND_REQUEST);
|
||||
|
||||
status = pjsip_tsx_send_msg(tsx, NULL);
|
||||
if (status != PJ_SUCCESS)
|
||||
if (status != PJ_SUCCESS) {
|
||||
if (tsx_data->timeout_timer.id != 0) {
|
||||
pjsip_endpt_cancel_timer(endpt, &tsx_data->timeout_timer);
|
||||
tsx_data->timeout_timer.id = PJ_FALSE;
|
||||
}
|
||||
pjsip_tx_data_dec_ref(tdata);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue