General update

This commit is contained in:
bossiel 2010-06-18 01:56:19 +00:00
parent 7540a04ffa
commit f56dc3b0dc
11 changed files with 281 additions and 54 deletions

View File

@ -338,9 +338,6 @@ const tsdp_header_M_t* tdav_session_audio_get_lo(tmedia_session_t* self)
TSK_OBJECT_SAFE_FREE(self->neg_codecs);
self->neg_codecs = neg_codecs;
}
else{
return tsk_null;
}
/* from codecs to sdp */
tmedia_codec_to_sdp(self->neg_codecs ? self->neg_codecs : self->codecs, self->M.lo);
@ -392,8 +389,6 @@ int tdav_session_audio_set_ro(tmedia_session_t* self, const tsdp_header_M_t* m)
/* update negociated codecs */
TSK_OBJECT_SAFE_FREE(self->neg_codecs);
self->neg_codecs = neg_codecs;
return 0;
}
else{
return -1;

View File

@ -70,7 +70,7 @@
# --pay hello world
#send INVITE
#++a --to sip:bob@$$(domain) >>(inv_audio_sid)
#++a --to sip:alice@$$(domain) >>(inv_audio_sid)
#++sleep --sec -1
#++ho --sid $$(inv_audio_sid)
#++sleep --sec -1

View File

@ -63,6 +63,7 @@ typedef enum _fsm_action_e
_fsm_action_iBYE,
_fsm_action_iREFER,
_fsm_action_timer100rel,
_fsm_action_timerRefresh,
_fsm_action_timerRSVP,

View File

@ -49,7 +49,9 @@ typedef struct tsip_dialog_invite
uint32_t rseq;
tsip_timer_t timershutdown;
tsip_timer_t timer100rel;
tsip_response_t* last_o1xxrel;
tsip_request_t* last_iInvite;
tsip_request_t* last_oInvite;
tmedia_session_mgr_t* msession_mgr; /**< Media session Manager. */
@ -66,8 +68,18 @@ typedef struct tsip_dialog_invite
enum tmedia_qos_stype_e type;
enum tmedia_qos_strength_e strength;
} qos;
/* 100rel */
unsigned enable_100rel:1;
struct{
unsigned _100rel:1;
unsigned precondition:1;
unsigned timer:1;
} supported;
struct{
unsigned _100rel:1;
unsigned precondition:1;
unsigned timer:1;
} require;
}
tsip_dialog_invite_t;

View File

@ -169,7 +169,7 @@ typedef struct tsip_header_s
}
tsip_header_t;
#define TSIP_DECLARE_HEADER tsip_header_t header
#define TSIP_DECLARE_HEADER tsip_header_t __header__
typedef tsk_list_t tsip_headers_L_t; /**< List of @ref tsip_header_t elements. */
/*
================================*/

View File

@ -459,6 +459,9 @@ int tsip_dialog_response_send(const tsip_dialog_t *self, tsip_response_t* respon
}
}
}
else{
TSK_DEBUG_ERROR("Invalid parameter");
}
return ret;
}

View File

@ -221,6 +221,9 @@ int tsip_dialog_invite_timer_callback(const tsip_dialog_invite_t* self, tsk_time
if(timer_id == self->stimers.timer.id){
ret = tsip_dialog_fsm_act(TSIP_DIALOG(self), _fsm_action_timerRefresh, tsk_null, tsk_null);
}
else if(timer_id == self->timer100rel.id){
ret = tsip_dialog_fsm_act(TSIP_DIALOG(self), _fsm_action_timer100rel, tsk_null, tsk_null);
}
else if(timer_id == self->qos.timer.id){
ret = tsip_dialog_fsm_act(TSIP_DIALOG(self), _fsm_action_timerRSVP, tsk_null, tsk_null);
}
@ -315,8 +318,8 @@ int tsip_dialog_invite_init(tsip_dialog_invite_t *self)
TSIP_DIALOG(self)->callback = TSIP_DIALOG_EVENT_CALLBACK_F(tsip_dialog_invite_event_callback);
/* Timers */
//self->timerrefresh.id = TSK_INVALID_TIMER_ID;
//self->timerrefresh.timeout = ;
self->timer100rel.id = TSK_INVALID_TIMER_ID;
self->stimers.timer.id = TSK_INVALID_TIMER_ID;
self->timershutdown.id = TSK_INVALID_TIMER_ID;
self->timershutdown.timeout = TSIP_DIALOG_SHUTDOWN_TIMEOUT;
@ -666,12 +669,23 @@ int send_INVITEorUPDATE(tsip_dialog_invite_t *self, tsk_bool_t is_INVITE, tsk_bo
/* Session timers */
if(self->stimers.timer.timeout){
tsip_message_add_headers(request,
TSIP_HEADER_SESSION_EXPIRES_VA_ARGS(self->stimers.timer.timeout, tsk_striequals(self->stimers.refresher, "uas")),
TSIP_HEADER_SUPPORTED_VA_ARGS("timer"),
tsk_null
);
if(self->require.timer){
tsip_message_add_headers(request,
TSIP_HEADER_SESSION_EXPIRES_VA_ARGS(self->stimers.timer.timeout, tsk_striequals(self->stimers.refresher, "uas")),
TSIP_HEADER_REQUIRE_VA_ARGS("timer"),
tsk_null
);
}
else if(self->supported.timer){
tsip_message_add_headers(request,
TSIP_HEADER_SESSION_EXPIRES_VA_ARGS(self->stimers.timer.timeout, tsk_striequals(self->stimers.refresher, "uas")),
TSIP_HEADER_SUPPORTED_VA_ARGS("timer"),
tsk_null
);
}
}
if(self->stimers.minse){
tsip_message_add_headers(request,
TSIP_HEADER_MIN_SE_VA_ARGS(self->stimers.minse),
@ -680,7 +694,13 @@ int send_INVITEorUPDATE(tsip_dialog_invite_t *self, tsk_bool_t is_INVITE, tsk_bo
}
/* 100rel */
if(self->enable_100rel){
if(self->require._100rel){
tsip_message_add_headers(request,
TSIP_HEADER_REQUIRE_VA_ARGS("100rel"),
tsk_null
);
}
else if(self->supported._100rel){
tsip_message_add_headers(request,
TSIP_HEADER_SUPPORTED_VA_ARGS("100rel"),
tsk_null
@ -688,20 +708,19 @@ int send_INVITEorUPDATE(tsip_dialog_invite_t *self, tsk_bool_t is_INVITE, tsk_bo
}
/* QoS */
if(self->qos.type != tmedia_qos_stype_none){
if(self->qos.strength == tmedia_qos_strength_mandatory){
tsip_message_add_headers(request,
TSIP_HEADER_REQUIRE_VA_ARGS("precondition"),
tsk_null
);
}
else{
tsip_message_add_headers(request,
TSIP_HEADER_SUPPORTED_VA_ARGS("precondition"),
tsk_null
);
}
if(self->require.precondition){
tsip_message_add_headers(request,
TSIP_HEADER_REQUIRE_VA_ARGS("precondition"),
tsk_null
);
}
else if(self->supported.precondition){
tsip_message_add_headers(request,
TSIP_HEADER_SUPPORTED_VA_ARGS("precondition"),
tsk_null
);
}
/* Always added headers */
// Explicit Communication Transfer (3GPP TS 24.629)
@ -973,6 +992,28 @@ int send_RESPONSE(tsip_dialog_invite_t *self, const tsip_request_t* request, sho
);
}
/* 180 Ringing */
/* 183 Session in Progress */
if(code == 180 || code == 183){
if(self->require._100rel){
tsip_message_add_headers(response,
TSIP_HEADER_REQUIRE_VA_ARGS("100rel"),
TSIP_HEADER_RSEQ_VA_ARGS(self->rseq),
tsk_null
);
TSK_OBJECT_SAFE_FREE(self->last_o1xxrel);
self->last_o1xxrel = tsk_object_ref(response);
/* No-Initial reliable 1xx will use tsip_dialog_response_send() instead of this function
* ==> can reseset timeout value and make initial schedule */
TSIP_DIALOG_TIMER_CANCEL(100rel);
self->timer100rel.timeout = tsip_timers_getA();
TSIP_DIALOG_INVITE_TIMER_SCHEDULE(100rel);
}
}
/* SDP content */
if(self->msession_mgr && force_sdp){
const tsdp_message_t* sdp_lo;
char* sdp;
@ -995,6 +1036,28 @@ int send_RESPONSE(tsip_dialog_invite_t *self, const tsip_request_t* request, sho
return ret;
}
int send_ERROR(tsip_dialog_invite_t* self, const tsip_request_t* request, short code, const char* phrase, const char* reason)
{
tsip_response_t *response;
if(!self){
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
if((response = tsip_dialog_response_new(TSIP_DIALOG(self), code, phrase, request))){
// Add UnSupported header
tsip_message_add_headers(response,
TSIP_HEADER_DUMMY_VA_ARGS("Reason", reason),
tsk_null
);
tsip_dialog_response_send(TSIP_DIALOG(self), response);
TSK_OBJECT_SAFE_FREE(response);
}
return 0;
}
int tsip_dialog_invite_OnTerminated(tsip_dialog_invite_t *self)
{
TSK_DEBUG_INFO("=== INVITE Dialog terminated ===");
@ -1063,6 +1126,7 @@ static tsk_object_t* tsip_dialog_invite_dtor(tsk_object_t * _self)
tsip_dialog_invite_stimers_cancel(self);
tsip_dialog_invite_qos_timer_cancel(self);
TSIP_DIALOG_TIMER_CANCEL(shutdown);
TSIP_DIALOG_TIMER_CANCEL(100rel);
/* DeInitialize base class */
tsip_dialog_deinit(TSIP_DIALOG(self));
@ -1071,6 +1135,7 @@ static tsk_object_t* tsip_dialog_invite_dtor(tsk_object_t * _self)
TSK_OBJECT_SAFE_FREE(self->msession_mgr);
TSK_OBJECT_SAFE_FREE(self->last_oInvite);
TSK_OBJECT_SAFE_FREE(self->last_iInvite);
TSK_OBJECT_SAFE_FREE(self->last_o1xxrel);
TSK_FREE(self->stimers.refresher);
//...

View File

@ -133,6 +133,7 @@ int c0000_Started_2_Outgoing_X_oINVITE(va_list *app)
if(TSIP_DIALOG_GET_SS(self)->media.timers.timeout){
self->stimers.timer.timeout = TSIP_DIALOG_GET_SS(self)->media.timers.timeout;
tsk_strupdate(&self->stimers.refresher, TSIP_DIALOG_GET_SS(self)->media.timers.refresher);
self->supported.timer = tsk_true;
}
/* QoS
@ -143,9 +144,11 @@ int c0000_Started_2_Outgoing_X_oINVITE(va_list *app)
self->qos.type = TSIP_DIALOG_GET_SS(self)->media.qos.type;
self->qos.strength = TSIP_DIALOG_GET_SS(self)->media.qos.strength;
tmedia_session_mgr_set_qos(self->msession_mgr, self->qos.type, self->qos.strength);
self->supported.precondition = (self->qos.strength == tmedia_qos_strength_optional);
self->require.precondition = (self->qos.strength == tmedia_qos_strength_mandatory);
/* 100rel */
self->enable_100rel = TSIP_DIALOG_GET_SS(self)->media.enable_100rel;
self->supported._100rel = TSIP_DIALOG_GET_SS(self)->media.enable_100rel;
/* send the request */
ret = send_INVITE(self, tsk_false);
@ -180,8 +183,7 @@ int c0000_Outgoing_2_Connected_X_i2xxINVITE(va_list *app)
ret = send_ACK(self, r2xxINVITE);
}
/* Determine whether the remote party support UPDATE
* FIXME: do the same in server side */
/* Determine whether the remote party support UPDATE */
self->support_update = tsip_message_allowed(r2xxINVITE, "UPDATE");
/* Session Timers */

View File

@ -35,16 +35,22 @@
#include "tinysip/headers/tsip_header_Dummy.h"
#include "tinysip/headers/tsip_header_Min_SE.h"
#include "tinysip/headers/tsip_header_RAck.h"
#include "tinysip/headers/tsip_header_Require.h"
#include "tinysip/headers/tsip_header_Session_Expires.h"
#include "tsk_debug.h"
static const char* supported_options[] = { "100rel", "precondition8", "timer" };
static const char* supported_options[] = { "100rel", "precondition", "timer" };
/* ======================== external functions ======================== */
extern int send_RESPONSE(tsip_dialog_invite_t *self, const tsip_request_t* request, short code, const char* phrase, tsk_bool_t force_sdp);
extern int tsip_dialog_invite_process_ro(tsip_dialog_invite_t *self, const tsip_message_t* message);
extern int tsip_dialog_invite_stimers_schedule(tsip_dialog_invite_t* self, uint64_t timeout);
extern tsk_bool_t tsip_dialog_invite_stimers_isRefresher(tsip_dialog_invite_t* self);
extern int send_ERROR(tsip_dialog_invite_t* self, const tsip_request_t* request, short code, const char* phrase, const char* reason);
extern int tsip_dialog_invite_timer_callback(const tsip_dialog_invite_t* self, tsk_timer_id_t timer_id);
/* ======================== internal functions ======================== */
int send_UNSUPPORTED(tsip_dialog_invite_t* self, const tsip_request_t* request, const char* option);
@ -63,6 +69,7 @@ int s0000_Ringing_2_Ringing_X_iPRACK(va_list *app); // Alert user
int s0000_Ringing_2_Connected_X_Accept(va_list *app);
int s0000_Ringing_2_Terminated_X_Reject(va_list *app);
int s0000_Ringing_2_Terminated_X_iCANCEL(va_list *app);
int s0000_Any_2_Any_X_timer100rel(va_list *app);
/* ======================== conds ======================== */
static tsk_bool_t _fsm_cond_bad_extension(tsip_dialog_invite_t* self, tsip_message_t* message)
@ -72,7 +79,7 @@ static tsk_bool_t _fsm_cond_bad_extension(tsip_dialog_invite_t* self, tsip_messa
tsk_size_t i, j;
/* Check if we support all extensions */
for(i = 0; (requireHdr = (const tsip_header_Require_t*)tsip_message_get_header(message, tsip_htype_Require)); i++){
for(i = 0; (requireHdr = (const tsip_header_Require_t*)tsip_message_get_headerAt(message, tsip_htype_Require, i)); i++){
tsk_bool_t bad_extension = tsk_false;
const tsk_string_t* option = tsk_null;
tsk_list_foreach(item, requireHdr->options){
@ -105,7 +112,7 @@ static tsk_bool_t _fsm_cond_bad_content(tsip_dialog_invite_t* self, tsip_message
/* Check remote offer */
if((ret = tsip_dialog_invite_process_ro(self, message))){
send_RESPONSE(self, message, 488, "Not Acceptable", tsk_false);
ret = send_ERROR(self, self->last_iInvite, 488, "Not Acceptable", "SIP; cause=488; text=\"Bad content\"");
return tsk_true;
}
/* generate local offer and check it's validity */
@ -113,7 +120,7 @@ static tsk_bool_t _fsm_cond_bad_content(tsip_dialog_invite_t* self, tsip_message
/* check that we have at least one codec */
}
else{
send_RESPONSE(self, message, 488, "Not Acceptable", tsk_false);
ret = send_ERROR(self, self->last_iInvite, 488, "Not Acceptable", "SIP; cause=488; text=\"Bad content\"");
return tsk_true;
}
@ -142,7 +149,6 @@ static tsk_bool_t _fsm_cond_toosmall(tsip_dialog_invite_t* self, tsip_message_t*
}
return tsk_false;
}
static tsk_bool_t _fsm_cond_supports_100rel(tsip_dialog_invite_t* self, tsip_message_t* message)
{
if(tsip_message_supported(message, "100rel") || tsip_message_required(message, "100rel")){
@ -150,7 +156,22 @@ static tsk_bool_t _fsm_cond_supports_100rel(tsip_dialog_invite_t* self, tsip_mes
}
return tsk_false;
}
static tsk_bool_t _fsm_cond_prack_match(tsip_dialog_invite_t* self, tsip_message_t* message)
{
const tsip_header_RAck_t* RAck;
if(!self->last_o1xxrel){
return tsk_false;
}
if((RAck = (const tsip_header_RAck_t*)tsip_message_get_header(message, tsip_htype_RAck))){
return (RAck->seq == self->rseq) &&
(tsk_striequals(RAck->method, self->last_o1xxrel->CSeq->method)) &&
(RAck->cseq == self->last_o1xxrel->CSeq->seq);
}
return tsk_false;
}
static tsk_bool_t _fsm_cond_supports_preconditions(tsip_dialog_invite_t* self, tsip_message_t* message)
{
// supports or require
@ -187,7 +208,7 @@ int tsip_dialog_invite_server_init(tsip_dialog_invite_t *self)
// InProgress ->(iPRACK with QoS) -> InProgress
TSK_FSM_ADD(_fsm_state_InProgress, _fsm_action_iPRACK, _fsm_cond_supports_preconditions, _fsm_state_InProgress, s0000_InProgress_2_InProgress_X_iPRACK, "s0000_InProgress_2_InProgress_X_iPRACK"),
// InProgress ->(iPRACK without QoS) -> Ringing
TSK_FSM_ADD_ALWAYS(_fsm_state_InProgress, _fsm_action_iPRACK, _fsm_state_Ringing, s0000_InProgress_2_Ringing_X_iPRACK, "s0000_InProgress_2_Ringing_X_iPRACK"),
TSK_FSM_ADD(_fsm_state_InProgress, _fsm_action_iPRACK, _fsm_cond_prack_match, _fsm_state_Ringing, s0000_InProgress_2_Ringing_X_iPRACK, "s0000_InProgress_2_Ringing_X_iPRACK"),
// InProgress ->(iUPDATE but cannot resume) -> InProgress
TSK_FSM_ADD(_fsm_state_InProgress, _fsm_action_iUPDATE, _fsm_cond_cannotresume, _fsm_state_InProgress, s0000_InProgress_2_InProgress_X_iUPDATE, "s0000_InProgress_2_InProgress_X_iUPDATE"),
// InProgress ->(iUPDATE can resume) -> Ringing
@ -200,7 +221,7 @@ int tsip_dialog_invite_server_init(tsip_dialog_invite_t *self)
* === Ringing ===
*/
// Ringing -> (iPRACK) -> Ringing
TSK_FSM_ADD_ALWAYS(_fsm_state_Ringing, _fsm_action_iUPDATE, _fsm_state_Ringing, s0000_Ringing_2_Ringing_X_iPRACK, "s0000_Ringing_2_Ringing_X_iPRACK"),
TSK_FSM_ADD(_fsm_state_Ringing, _fsm_action_iPRACK, _fsm_cond_prack_match, _fsm_state_Ringing, s0000_Ringing_2_Ringing_X_iPRACK, "s0000_Ringing_2_Ringing_X_iPRACK"),
// Ringing -> (oAccept) -> Connected
TSK_FSM_ADD_ALWAYS(_fsm_state_Ringing, _fsm_action_accept, _fsm_state_Connected, s0000_Ringing_2_Connected_X_Accept, "s0000_Ringing_2_Connected_X_Accept"),
// Ringing -> (oReject) -> Terminated
@ -208,6 +229,14 @@ int tsip_dialog_invite_server_init(tsip_dialog_invite_t *self)
// Ringing ->(iCANCEL) -> Terminated
TSK_FSM_ADD_ALWAYS(_fsm_state_Ringing, _fsm_action_iCANCEL, _fsm_state_Terminated, s0000_Ringing_2_Terminated_X_iCANCEL, "s0000_Ringing_2_Terminated_X_iCANCEL"),
/*=======================
* === ANY ===
*/
// Any ->(timer100rel) -> Any
TSK_FSM_ADD_ALWAYS(tsk_fsm_state_any, _fsm_action_timer100rel, tsk_fsm_state_any, s0000_Any_2_Any_X_timer100rel, "s0000_Any_2_Any_X_timer100rel"),
TSK_FSM_ADD_NULL());
}
@ -271,27 +300,91 @@ int s0000_Started_2_Ringing_X_iINVITE(va_list *app)
return 0;
}
/* Started -> (100rel or QoS, ther later need the first) -> InProgress */
/* Started -> (100rel or QoS, the later need the first) -> InProgress */
int s0000_Started_2_InProgress_X_iINVITE(va_list *app)
{
tsip_dialog_invite_t *self = va_arg(*app, tsip_dialog_invite_t *);
tsip_request_t *request = va_arg(*app, tsip_request_t *);
/* We are not the client */
self->is_client = tsk_false;
/* update last INVITE */
TSK_OBJECT_SAFE_FREE(self->last_iInvite);
self->last_iInvite = tsk_object_ref(request);
/* Update state */
tsip_dialog_update_2(TSIP_DIALOG(self), request);
/* Send In Progress
RFC 3262 - 3 UAS Behavior
The provisional response to be sent reliably is constructed by the
UAS core according to the procedures of Section 8.2.6 of RFC 3261.
In addition, it MUST contain a Require header field containing the
option tag 100rel, and MUST include an RSeq header field. The value
of the header field for the first reliable provisional response in a
transaction MUST be between 1 and 2**31 - 1.
*/
self->rseq = (rand() ^ rand()) % (0x00000001 << 31);
self->require._100rel = tsk_true;
send_RESPONSE(self, request, 183, "Session in Progress", tsk_true);
return 0;
}
/* InProgress ->(iPRACK with QoS) -> InProgress */
int s0000_InProgress_2_InProgress_X_iPRACK(va_list *app)
{
/* Cancel 100rel timer */
return 0;
}
/* InProgress ->(iPRACK without QoS) -> Ringing */
int s0000_InProgress_2_Ringing_X_iPRACK(va_list *app)
{
return 0;
int ret;
tsip_dialog_invite_t *self = va_arg(*app, tsip_dialog_invite_t *);
tsip_request_t *request = va_arg(*app, tsip_request_t *);
/* In all cases: Send 2xx PRACK */
ret = send_RESPONSE(self, request, 200, "OK", tsk_false);
/*
1. Alice sends an initial INVITE without offer
2. Bob's answer is sent in the first reliable provisional response, in this case it's a 1xx INVITE response
3. Alice's answer is sent in the PRACK response
*/
if(!self->msession_mgr->sdp.ro){
if(TSIP_MESSAGE_HAS_CONTENT(request)){
if((ret = tsip_dialog_invite_process_ro(self, request))){
/* Send Error and break the FSM */
ret = send_ERROR(self, self->last_iInvite, 488, "Not Acceptable", "SIP; cause=488; text=\"Bad content\"");
return -4;
}
}
else{
/* 488 INVITE */
ret = send_ERROR(self, self->last_iInvite, 488, "Not Acceptable", "SIP; cause=488; text=\"Offer expected in the PRACK\"");
return -3;
}
}
/* Cancel 100rel timer */
TSIP_DIALOG_TIMER_CANCEL(100rel);
/* Send Ringing */
send_RESPONSE(self, self->last_iInvite, 180, "Ringing", tsk_false);
/* Alert the user (session) */
TSIP_DIALOG_INVITE_SIGNAL(self, tsip_i_newcall,
tsip_event_code_dialog_request_incoming, "Incoming Request.", request);
return ret;
}
/* InProgress ->(iUPDATE but cannot resume) -> InProgress */
@ -315,7 +408,23 @@ int s0000_Inprogress_2_Terminated_X_iCANCEL(va_list *app)
/* Ringing -> (iPRACK) -> Ringing */
int s0000_Ringing_2_Ringing_X_iPRACK(va_list *app)
{
return 0;
int ret;
tsip_dialog_invite_t *self = va_arg(*app, tsip_dialog_invite_t *);
tsip_request_t *request = va_arg(*app, tsip_request_t *);
if(!self->last_iInvite){
/* silently ignore */
return 0;
}
/* Cancel 100rel timer */
TSIP_DIALOG_TIMER_CANCEL(100rel);
/* Send 2xx PRACK */
ret = send_RESPONSE(self, request, 200, "OK", tsk_false);
return ret;
}
/* Ringing -> (oAccept) -> Connected */
@ -333,6 +442,9 @@ int s0000_Ringing_2_Connected_X_Accept(va_list *app)
/* Update current action */
tsip_dialog_set_curr_action(TSIP_DIALOG(self), action);
/* Determine whether the remote party support UPDATE */
self->support_update = tsip_message_allowed(self->last_iInvite, "UPDATE");
/* start session manager */
if(self->msession_mgr && !self->msession_mgr->started){
ret = tmedia_session_mgr_start(self->msession_mgr);
@ -341,15 +453,19 @@ int s0000_Ringing_2_Connected_X_Accept(va_list *app)
/* send 2xx OK */
ret = send_RESPONSE(self, self->last_iInvite, 200, "OK", tsk_true);
/* RFC 4825 - 9. UAS Behavior
UAC supports? refresher parameter refresher parameter
in request in response
-------------------------------------------------------
Y none uas or uac
Y uac uac
Y uas uas
*/
/* Session Timers */
if(self->stimers.timer.timeout){
if(tsip_dialog_invite_stimers_isRefresher(self)){
/* RFC 4028 - 9. UAS Behavior
It is RECOMMENDED that this refresh be sent oncehalf the session interval has elapsed.
Additional procedures for this refresh are described in Section 10.
*/
tsip_dialog_invite_stimers_schedule(self, (self->stimers.timer.timeout*1000)/2);
}
else{
tsip_dialog_invite_stimers_schedule(self, (self->stimers.timer.timeout*1000));
}
}
return ret;
}
@ -366,6 +482,35 @@ int s0000_Ringing_2_Terminated_X_iCANCEL(va_list *app)
return 0;
}
/* Any ->(timer 100rel) -> Any */
int s0000_Any_2_Any_X_timer100rel(va_list *app)
{
tsip_dialog_invite_t *self = va_arg(*app, tsip_dialog_invite_t *);
int ret;
if(!self->last_o1xxrel){
/* silently ignore */
return 0;
}
/* resync timer */
if((self->timer100rel.timeout *= 2) >= (64 * tsip_timers_getA())){
TSK_DEBUG_ERROR("Sending reliable 1xx failed");
return -2;
}
/* resend reliable 1xx */
if((ret = tsip_dialog_response_send(TSIP_DIALOG(self), self->last_o1xxrel))){
return ret;
}
else{
/* schedule timer */
TSIP_DIALOG_INVITE_TIMER_SCHEDULE(100rel);
}
return ret;
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// == STATE MACHINE END ==
@ -393,3 +538,5 @@ int send_UNSUPPORTED(tsip_dialog_invite_t* self, const tsip_request_t* request,
}
return 0;
}

View File

@ -264,6 +264,7 @@ int tsip_dialog_invite_stimers_handle(tsip_dialog_invite_t* self, const tsip_mes
if(tsk_strnullORempty(self->stimers.refresher)){
tsk_strupdate(&self->stimers.refresher, hdr_SessionExpires->refresher_uas ? "uas" : "uac");
}
self->supported.timer = (self->stimers.timer.timeout != 0);
}
}
else{
@ -283,6 +284,7 @@ int tsip_dialog_invite_stimers_handle(tsip_dialog_invite_t* self, const tsip_mes
without a Session-Expires header field.
*/
self->stimers.timer.timeout = 0; /* turned-off */
self->supported.timer = tsk_false;
}
}

View File

@ -45,7 +45,7 @@
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\thirdparties\win32\include;..\tinySIP\include;..\tinySAK\src;..\tinyNET\src;..\tinyHTTP\include;..\tinySIGCOMP\src;..\tinyIPSec\src;..\tinySDP\include;..\tinyMEDIA\include"
PreprocessorDefinitions="DEBUG_LEVEL=DEBUG_LEVEL_INFO;SDS_HACK;WIN32;_DEBUG;_WINDOWS;_USRDLL;TINYSIP_EXPORTS;_WIN32_WINNT 0x0501"
PreprocessorDefinitions="DEBUG_LEVEL=DEBUG_LEVEL_INFO;WIN32;_DEBUG;_WINDOWS;_USRDLL;TINYSIP_EXPORTS;_WIN32_WINNT 0x0501"
MinimalRebuild="true"
RuntimeLibrary="3"
UsePrecompiledHeader="0"