Begin implementing INVITE Client Transaction (ICT) with Fixes as per draft-sparks-sip-invfix-0.

This commit is contained in:
bossiel 2010-03-17 01:20:38 +00:00
parent 299e397a9f
commit 87cfb8989a
16 changed files with 851 additions and 118 deletions

View File

@ -21,7 +21,7 @@
*/
/**@file tsdp_header_B.c
/**@file tsdp_header_A.c
* @brief SDP "a=" header (Attributes).
*
* @author Mamadou Diop <diopmamadou(at)yahoo.fr>

View File

@ -21,8 +21,8 @@
*/
/**@file tsdp_header_I.c
* @brief SDP "i=" header (Session Information).
/**@file tsdp_header_E.c
* @brief SDP "e=" header (Session Information).
*
* @author Mamadou Diop <diopmamadou(at)yahoo.fr>
*

View File

@ -21,7 +21,7 @@
*/
/**@file tsdp_header_B.c
/**@file tsdp_header_M.c
* @brief SDP "m=" header (Media Descriptions).
*
* @author Mamadou Diop <diopmamadou(at)yahoo.fr>

View File

@ -21,7 +21,7 @@
*/
/**@file tsdp_header_C.c
/**@file tsdp_header_R.c
* @brief SDP "r=" header (Repeat Times).
*
* @author Mamadou Diop <diopmamadou(at)yahoo.fr>

View File

@ -31,21 +31,33 @@
#define TINYSIP_TRANSAC_ICT_H
#include "tinySIP_config.h"
#include "tinySIP/transactions/tsip_transac.h"
#include "tinySIP/tsip_message.h"
#include "tsk_fsm.h"
TSIP_BEGIN_DECLS
#define TSIP_TRANSAC_ICT_CREATE(stack, reliable, cseq_value, callid) tsk_object_new(tsip_transac_ict_def_t, (const tsip_stack_handle_t *)stack, (unsigned)reliable, (int32_t)cseq_value, (const char*)callid)
#define TSIP_TRANSAC_ICT(self) ((tsip_transac_ict_t*)(self))
typedef struct tsip_transac_ict
{
TSIP_DECLARE_TRANSAC;
tsk_fsm_t *fsm;
tsip_request_t* request;
tsip_timer_t timerA;
tsip_timer_t timerB;
tsip_timer_t timerD;
tsip_timer_t timerM;
}
tsip_transac_ict_t;
int tsip_transac_ict_init(tsip_transac_ict_t *self);
int tsip_transac_ict_start(tsip_transac_ict_t *self, const tsip_request_t* request);
TSIP_END_DECLS

View File

@ -83,6 +83,20 @@ TSIP_BEGIN_DECLS
#define TSIP_MESSAGE_CONTENT_LENGTH(message) (uint32_t)(((message) && (message)->Content_Length) ? (message)->Content_Length->length : 0)
#define TSIP_MESSAGE_CONTENT(message) (TSIP_MESSAGE_HAS_CONTENT(message) ? (message)->Content->data : 0)
#define TSIP_REQUEST_IS_ACK(self) ((self) &&((self)->request_type==tsip_ACK))
#define TSIP_REQUEST_IS_BYE(self) ((self) &&((self)->request_type==tsip_BYE))
#define TSIP_REQUEST_IS_CANCEL(self) ((self) &&((self)->request_type==tsip_CANCEL))
#define TSIP_REQUEST_IS_INVITE(self) ((self) &&((self)->request_type==tsip_INVITE))
#define TSIP_REQUEST_IS_OPTIONS(self) ((self) &&((self)->request_type==tsip_OPTIONS))
#define TSIP_REQUEST_IS_REGISTER(self) ((self) &&((self)->request_type==tsip_REGISTER))
#define TSIP_REQUEST_IS_SUBSCRIBE(self) ((self) &&((self)->request_type==tsip_SUBSCRIBE))
#define TSIP_REQUEST_IS_NOTIFY(self) ((self) &&((self)->request_type==tsip_NOTIFY))
#define TSIP_REQUEST_IS_REFER(self) ((self) &&((self)->request_type==tsip_REFER))
#define TSIP_REQUEST_IS_INFO(self) ((self) &&((self)->request_type==tsip_INFO))
#define TSIP_REQUEST_IS_UPDATE(self) ((self) &&((self)->request_type==tsip_UPDATE))
#define TSIP_REQUEST_IS_MESSAGE(self) ((self) &&((self)->request_type==tsip_MESSAGE))
#define TSIP_REQUEST_IS_PUBLISH(self) ((self) &&((self)->request_type==tsip_PUBLISH))
#define TSIP_REQUEST_IS_PRACK(self) ((self) &&((self)->request_type==tsip_PRACK))
#define TSIP_RESPONSE_IS(self, code) (TSIP_RESPONSE_CODE((self)) == code)
#define TSIP_RESPONSE_IS_NXX(self, N) (TSIP_MESSAGE_IS_RESPONSE((self)) && N##00<= TSIP_RESPONSE_CODE((self)) && TSIP_RESPONSE_CODE((self)) <= N##99)
@ -93,6 +107,7 @@ TSIP_BEGIN_DECLS
#define TSIP_RESPONSE_IS_5XX(self) TSIP_RESPONSE_IS_NXX(self, 5)
#define TSIP_RESPONSE_IS_6XX(self) TSIP_RESPONSE_IS_NXX(self, 6)
#define TSIP_RESPONSE_IS_23456(self) (TSIP_MESSAGE_IS_RESPONSE((self)) && 200<= TSIP_RESPONSE_CODE((self)) && TSIP_RESPONSE_CODE((self)) <= 699)
#define TSIP_RESPONSE_IS_3456(self) (TSIP_MESSAGE_IS_RESPONSE((self)) && 300<= TSIP_RESPONSE_CODE((self)) && TSIP_RESPONSE_CODE((self)) <= 699)
/**
* @enum tsip_message_type_t

View File

@ -52,6 +52,8 @@ TSIP_BEGIN_DECLS
//extern const char *timerI;
//extern const char *timerJ;
//extern const char *timerK;
//extern const char *timerL;
//extern const char *timerM;
typedef struct tsip_timer_s
{
@ -76,6 +78,8 @@ typedef struct tsip_timers_s
uint32_t I;
uint32_t J;
uint32_t K;
uint32_t L;
uint32_t M;
}
tsip_timers_t;
@ -93,6 +97,8 @@ TINYSIP_API void tsip_timers_setH(uint32_t h);
TINYSIP_API void tsip_timers_setI(uint32_t i);
TINYSIP_API void tsip_timers_setJ(uint32_t j);
TINYSIP_API void tsip_timers_setK(uint32_t k);
TINYSIP_API void tsip_timers_setL(uint32_t l);
TINYSIP_API void tsip_timers_setM(uint32_t m);
TINYSIP_API uint32_t tsip_timers_getT1();
TINYSIP_API uint32_t tsip_timers_getT2();
@ -108,6 +114,8 @@ TINYSIP_API uint32_t tsip_timers_getH();
TINYSIP_API uint32_t tsip_timers_getI();
TINYSIP_API uint32_t tsip_timers_getJ();
TINYSIP_API uint32_t tsip_timers_getK();
TINYSIP_API uint32_t tsip_timers_getL();
TINYSIP_API uint32_t tsip_timers_getM();
TSIP_END_DECLS

View File

@ -273,7 +273,7 @@ tsip_request_t *tsip_dialog_request_new(const tsip_dialog_t *self, const char* m
c) and the values received in the Service-Route header field saved from the 200 (OK) response to the last
registration or re-registration of the public user identity with associated contact address.
*/
if(request->request_type != tsip_REGISTER)
if(!TSIP_REQUEST_IS_REGISTER(request))
{ // According to the above link ==> Initial/Re/De registration do not have routes.
if(copy_routes_start != -1)
{ /* The dialog already have routes ==> copy them. */
@ -778,7 +778,7 @@ int tsip_dialog_add_common_headers(const tsip_dialog_t *self, tsip_request_t* re
case tsip_PUBLISH:
case tsip_REGISTER:
{
if(!earlyIMS || (earlyIMS && request->request_type == tsip_REGISTER)){
if(!earlyIMS || (earlyIMS && TSIP_REQUEST_IS_REGISTER(request))){
TSIP_MESSAGE_ADD_HEADER(request, TSIP_HEADER_P_PREFERRED_IDENTITY_VA_ARGS(preferred_identity));
}
break;

View File

@ -170,7 +170,7 @@ int tsip_dialog_subscribe_event_callback(const tsip_dialog_subscribe_t *self, ts
//
// REQUEST
//
if(msg->request_type == tsip_NOTIFY){
if(TSIP_REQUEST_IS_NOTIFY(msg)){
ret = tsk_fsm_act((self)->fsm, _fsm_action_notify, self, msg, self, msg);
}
}

View File

@ -20,6 +20,56 @@
*
*/
/*=============================================================================
* IMPORTANT: The INVITE Client Transaction (ICT) implements corrections defined in 'draft-sparks-sip-invfix-02.txt'.
* which fixes RFC 3261. This will alow us to easily suppoort forking.
|INVITE from TU
Timer A fires |INVITE sent Timer B fired
Reset A, V or Transport Err.
INVITE sent +-----------+ inform TU
+---------| |--------------------------+
| | Calling | |
+-------->| |-----------+ |
300-699 +-----------+ 2xx | |
ACK sent | | 2xx to TU | |
resp. to TU | |1xx | |
+-----------------------------+ |1xx to TU | |
| | | |
| 1xx V | |
| 1xx to TU +-----------+ | |
| +---------| | | |
| | |Proceeding | | |
| +-------->| | | |
| +-----------+ 2xx | |
| 300-699 | | 2xx to TU | |
| ACK sent, +--------+ +---------------+ |
| resp. to TU| | |
| | | |
| V V |
| +-----------+ +----------+ |
+------------->| |Transport Err. | | |
| Completed |Inform TU | Accepted | |
+--| |-------+ | |-+ |
300-699 | +-----------+ | +----------+ | |
ACK sent| ^ | | | ^ | |
| | | | | | | |
+----+ | | | +-----+ |
|Timer D fires | Timer M fires| 2xx |
|- | - | 2xx to TU |
+--------+ | +-----------+ |
NOTE: V V V |
transitions +------------+ |
labeled with | | |
the event | Terminated |<-----------------------+
over the action | |
to take +------------+
draft-sparks-sip-invfix-02.txt - Figure 3: INVITE client transaction
=============================================================================*/
/**@file tsip_transac_ict.c
* @brief SIP INVITE Client Transaction as per RFC 3261 subclause 17.1.1.
*
@ -29,7 +79,679 @@
*/
#include "tinySIP/transactions/tsip_transac_ict.h"
#include "tsk_debug.h"
#define DEBUG_STATE_MACHINE 1
#define TRANSAC_ICT_TIMER_SCHEDULE(TX) TRANSAC_TIMER_SCHEDULE(ict, TX)
/* ======================== internal functions ======================== */
int tsip_transac_ict_init(tsip_transac_ict_t *self);
int tsip_transac_ict_send_ack(const tsip_response_t* response);
int tsip_transac_ict_OnTerminated(tsip_transac_ict_t *self);
/* ======================== transitions ======================== */
int tsip_transac_ict_Started_2_Calling_X_send(va_list *app);
int tsip_transac_ict_Calling_2_Calling_X_timerA(va_list *app);
int tsip_transac_ict_Calling_2_Terminated_X_timerB(va_list *app);
int tsip_transac_ict_Calling_2_Completed_X_300_to_699(va_list *app);
int tsip_transac_ict_Calling_2_Proceeding_X_1xx(va_list *app);
int tsip_transac_ict_Calling_2_Accepted_X_2xx(va_list *app);
int tsip_transac_ict_Proceeding_2_Proceeding_X_1xx(va_list *app);
int tsip_transac_ict_Proceeding_2_Completed_X_300_to_699(va_list *app);
int tsip_transac_ict_Proceeding_2_Accepted_X_2xx(va_list *app);
int tsip_transac_ict_Completed_2_Completed_X_300_to_699(va_list *app);
int tsip_transac_ict_Completed_2_Terminated_X_timerD(va_list *app);
int tsip_transac_ict_Accepted_2_Accepted_X_1xx(va_list *app);
int tsip_transac_ict_Accepted_2_Terminated_X_timerM(va_list *app);
int tsip_transac_ict_Any_2_Terminated_X_transportError(va_list *app);
int tsip_transac_ict_Any_2_Terminated_X_Error(va_list *app);
/* ======================== conds ======================== */
/* ======================== actions ======================== */
typedef enum _fsm_action_e
{
_fsm_action_send,
_fsm_action_timerA,
_fsm_action_timerB,
_fsm_action_timerD,
_fsm_action_timerM,
_fsm_action_1xx,
_fsm_action_2xx,
_fsm_action_300_to_699,
_fsm_action_transporterror,
_fsm_action_error,
}
_fsm_action_t;
/* ======================== states ======================== */
typedef enum _fsm_state_e
{
_fsm_state_Started,
_fsm_state_Calling,
_fsm_state_Proceeding,
_fsm_state_Completed,
_fsm_state_Accepted,
_fsm_state_Terminated
}
_fsm_state_t;
/**
* Callback function called by the transport layer to alert the transaction for incoming messages
* or errors (e.g. transport error).
*
* @param [in,out] self A pointer to the IC transaction.
* @param type The event type.
* @param [in,out] msg The incoming message.
*
* @return Zero if succeed and no-zero error code otherwise.
**/
int tsip_transac_ict_event_callback(const tsip_transac_ict_t *self, tsip_transac_event_type_t type, const tsip_message_t *msg)
{
int ret = 0;
switch(type)
{
case tsip_transac_incoming_msg:
{
if(msg && TSIP_MESSAGE_IS_RESPONSE(msg))
{
if(TSIP_RESPONSE_IS_1XX(msg)){
ret = tsk_fsm_act(self->fsm, _fsm_action_1xx, self, msg, self, msg);
}
else if(TSIP_RESPONSE_IS_2XX(msg)){
ret = tsk_fsm_act(self->fsm, _fsm_action_2xx, self, msg, self, msg);
}
else if(TSIP_RESPONSE_IS_3456(msg)){
ret = tsk_fsm_act(self->fsm, _fsm_action_300_to_699, self, msg, self, msg);
}
else{
TSK_DEBUG_WARN("Not supported status code: %d", TSIP_RESPONSE_CODE(msg));
}
}
break;
}
case tsip_transac_canceled:
case tsip_transac_terminated:
case tsip_transac_timedout:
break;
case tsip_transac_error:
{
ret = tsk_fsm_act(self->fsm, _fsm_action_error, self, msg, self, msg);
break;
}
case tsip_transac_transport_error:
{
ret = tsk_fsm_act(self->fsm, _fsm_action_transporterror, self, msg, self, msg);
break;
}
}
return ret;
}
int tsip_transac_ict_timer_callback(const tsip_transac_ict_t* self, tsk_timer_id_t timer_id)
{
int ret = -1;
if(self)
{
if(timer_id == self->timerA.id){
ret = tsk_fsm_act(self->fsm, _fsm_action_timerA, self, TSK_NULL, self, TSK_NULL);
}
else if(timer_id == self->timerB.id){
ret = tsk_fsm_act(self->fsm, _fsm_action_timerB, self, TSK_NULL, self, TSK_NULL);
}
else if(timer_id == self->timerD.id){
ret = tsk_fsm_act(self->fsm, _fsm_action_timerD, self, TSK_NULL, self, TSK_NULL);
}
else if(timer_id == self->timerM.id){
ret = tsk_fsm_act(self->fsm, _fsm_action_timerM, self, TSK_NULL, self, TSK_NULL);
}
}
return ret;
}
/** Initializes the transaction.
*
* @author Mamadou
* @date 12/24/2009
*
* @param [in,out] self The transaction to initialize.
**/
int tsip_transac_ict_init(tsip_transac_ict_t *self)
{
/* Initialize the state machine. */
tsk_fsm_set(self->fsm,
/*=======================
* === Started ===
*/
// Started -> (Send) -> Calling
TSK_FSM_ADD_ALWAYS(_fsm_state_Started, _fsm_action_send, _fsm_state_Calling, tsip_transac_ict_Started_2_Calling_X_send, "tsip_transac_ict_Started_2_Calling_X_send"),
// Started -> (Any) -> Started
TSK_FSM_ADD_ALWAYS_NOTHING(_fsm_state_Started, "tsip_transac_ict_Started_2_Started_X_any"),
/*=======================
* === Calling ===
*/
// Calling -> (timerA) -> Calling
TSK_FSM_ADD_ALWAYS(_fsm_state_Calling, _fsm_action_timerA, _fsm_state_Calling, tsip_transac_ict_Calling_2_Calling_X_timerA, "tsip_transac_ict_Calling_2_Calling_X_timerA"),
// Calling -> (timerB) -> Terminated
TSK_FSM_ADD_ALWAYS(_fsm_state_Calling, _fsm_action_timerB, _fsm_state_Terminated, tsip_transac_ict_Calling_2_Terminated_X_timerB, "tsip_transac_ict_Calling_2_Terminated_X_timerB"),
// Calling -> (300-699) -> Completed
TSK_FSM_ADD_ALWAYS(_fsm_state_Calling, _fsm_action_300_to_699, _fsm_state_Completed, tsip_transac_ict_Calling_2_Completed_X_300_to_699, "tsip_transac_ict_Calling_2_Completed_X_300_to_699"),
// Calling -> (1xx) -> Proceeding
TSK_FSM_ADD_ALWAYS(_fsm_state_Calling, _fsm_action_1xx, _fsm_state_Proceeding, tsip_transac_ict_Calling_2_Proceeding_X_1xx, "tsip_transac_ict_Calling_2_Proceeding_X_1xx"),
// Calling -> (2xx) -> Accepted
TSK_FSM_ADD_ALWAYS(_fsm_state_Calling, _fsm_action_2xx, _fsm_state_Accepted, tsip_transac_ict_Calling_2_Accepted_X_2xx, "tsip_transac_ict_Calling_2_Accepted_X_2xx"),
/*=======================
* === Proceeding ===
*/
// Proceeding -> (1xx) -> Proceeding
TSK_FSM_ADD_ALWAYS(_fsm_state_Proceeding, _fsm_action_1xx, _fsm_state_Proceeding, tsip_transac_ict_Proceeding_2_Proceeding_X_1xx, "tsip_transac_ict_Proceeding_2_Proceeding_X_1xx"),
// Proceeding -> (300-699) -> Completed
TSK_FSM_ADD_ALWAYS(_fsm_state_Proceeding, _fsm_action_300_to_699, _fsm_state_Completed, tsip_transac_ict_Proceeding_2_Completed_X_300_to_699, "tsip_transac_ict_Proceeding_2_Completed_X_300_to_699"),
// Proceeding -> (2xx) -> Accepted
TSK_FSM_ADD_ALWAYS(_fsm_state_Proceeding, _fsm_action_2xx, _fsm_state_Accepted, tsip_transac_ict_Proceeding_2_Accepted_X_2xx, "tsip_transac_ict_Proceeding_2_Accepted_X_2xx"),
/*=======================
* === Completed ===
*/
// Completed -> (300-699) -> Completed
TSK_FSM_ADD_ALWAYS(_fsm_state_Completed, _fsm_action_300_to_699, _fsm_state_Completed, tsip_transac_ict_Completed_2_Completed_X_300_to_699, "tsip_transac_ict_Completed_2_Completed_X_300_to_699"),
// Completed -> (timerD) -> Terminated
TSK_FSM_ADD_ALWAYS(_fsm_state_Completed, _fsm_action_timerD, _fsm_state_Terminated, tsip_transac_ict_Completed_2_Terminated_X_timerD, "tsip_transac_ict_Completed_2_Terminated_X_timerD"),
/*=======================
* === Accepted ===
*/
// Accepted -> (1xx) -> Accepted
TSK_FSM_ADD_ALWAYS(_fsm_state_Accepted, _fsm_action_1xx, _fsm_state_Accepted, tsip_transac_ict_Accepted_2_Accepted_X_1xx, "tsip_transac_ict_Accepted_2_Accepted_X_1xx"),
// Accepted -> (timerM) -> Terminated
TSK_FSM_ADD_ALWAYS(_fsm_state_Accepted, _fsm_action_timerM, _fsm_state_Terminated, tsip_transac_ict_Accepted_2_Terminated_X_timerM, "tsip_transac_ict_Accepted_2_Terminated_X_timerM"),
/*=======================
* === Any ===
*/
// Any -> (transport error) -> Terminated
TSK_FSM_ADD_ALWAYS(tsk_fsm_state_any, _fsm_action_transporterror, _fsm_state_Terminated, tsip_transac_ict_Any_2_Terminated_X_transportError, "tsip_transac_ict_Any_2_Terminated_X_transportError"),
// Any -> (transport error) -> Terminated
TSK_FSM_ADD_ALWAYS(tsk_fsm_state_any, _fsm_action_error, _fsm_state_Terminated, tsip_transac_ict_Any_2_Terminated_X_Error, "tsip_transac_ict_Any_2_Terminated_X_Error"),
TSK_FSM_ADD_NULL());
/* Set callback function to call when new messages arrive or errors happen in
the transport layer.
*/
TSIP_TRANSAC(self)->callback = TSIP_TRANSAC_EVENT_CALLBACK(tsip_transac_ict_event_callback);
/* Timers */
self->timerA.id = TSK_INVALID_TIMER_ID;
self->timerB.id = TSK_INVALID_TIMER_ID;
self->timerD.id = TSK_INVALID_TIMER_ID;
self->timerM.id = TSK_INVALID_TIMER_ID;
self->timerA.timeout = TSIP_TIMER_GET(A);
self->timerB.timeout = TSIP_TIMER_GET(B);
self->timerD.timeout = TSIP_TRANSAC(self)->reliable ? 0 : TSIP_TIMER_GET(D);
self->timerM.timeout = TSIP_TIMER_GET(M);
return 0;
}
/**
* Starts the client transaction.
*
* @param [in,out] self The client transaction to start.
* @param [in,out] request The SIP/IMS INVITE request to send.
*
* @return Zero if succeed and non-zero error code otherwise.
**/
int tsip_transac_ict_start(tsip_transac_ict_t *self, const tsip_request_t* request)
{
int ret = -1;
if(self && request && !TSIP_TRANSAC(self)->running)
{
/* Add branch to the new client transaction. */
if((TSIP_TRANSAC(self)->branch = tsk_strdup(TSIP_TRANSAC_MAGIC_COOKIE)))
{
tsk_istr_t branch;
tsk_strrandom(&branch);
tsk_strcat(&(TSIP_TRANSAC(self)->branch), branch);
}
TSIP_TRANSAC(self)->running = 1;
self->request = tsk_object_ref((void*)request);
ret = tsk_fsm_act(self->fsm, _fsm_action_send, self, TSK_NULL, self, TSK_NULL);
}
return ret;
}
//--------------------------------------------------------
// == STATE MACHINE BEGIN ==
//--------------------------------------------------------
/* Started -> (send) -> Calling
*/
int tsip_transac_ict_Started_2_Calling_X_send(va_list *app)
{
tsip_transac_ict_t *self = va_arg(*app, tsip_transac_ict_t *);
//const tsip_message_t *message = va_arg(*app, const tsip_message_t *);
//== Send the request
tsip_transac_send(TSIP_TRANSAC(self), TSIP_TRANSAC(self)->branch, TSIP_MESSAGE(self->request));
/* RFC 3261 - 17.1.1.2 Formal Description
If an unreliable transport is being used, the client transaction MUST
start timer A with a value of T1.
If a reliable transport is being used, the client transaction SHOULD
NOT start timer A (Timer A controls request retransmissions). For
any transport, the client transaction MUST start timer B with a value
of 64*T1 seconds (Timer B controls transaction timeouts).
*/
if(!TSIP_TRANSAC(self)->reliable){
TRANSAC_ICT_TIMER_SCHEDULE(A);
}
TRANSAC_ICT_TIMER_SCHEDULE(B);
return 0;
}
/* Calling -> (timerA) -> Calling
*/
int tsip_transac_ict_Calling_2_Calling_X_timerA(va_list *app)
{
tsip_transac_ict_t *self = va_arg(*app, tsip_transac_ict_t *);
//const tsip_message_t *message = va_arg(*app, const tsip_message_t *);
/* RFC 3261 - 17.1.1.2 Formal Description
When timer A fires, the client transaction MUST retransmit the
request by passing it to the transport layer, and MUST reset the
timer with a value of 2*T1. The formal definition of retransmit
within the context of the transaction layer is to take the message
previously sent to the transport layer and pass it to the transport
layer once more.
When timer A fires 2*T1 seconds later, the request MUST be
retransmitted again (assuming the client transaction is still in this
state). This process MUST continue so that the request is
retransmitted with intervals that double after each transmission.
These retransmissions SHOULD only be done while the client
transaction is in the "calling" state.
*/
//== Send the request
tsip_transac_send(TSIP_TRANSAC(self), TSIP_TRANSAC(self)->branch, self->request);
self->timerA.timeout *= 2; /* Will not raise indefinitely ==> see timer B */
TRANSAC_ICT_TIMER_SCHEDULE(A);
return 0;
}
/* Calling -> (timerB) -> Terminated
*/
int tsip_transac_ict_Calling_2_Terminated_X_timerB(va_list *app)
{
tsip_transac_ict_t *self = va_arg(*app, tsip_transac_ict_t *);
//const tsip_message_t *message = va_arg(*app, const tsip_message_t *);
/* RFC 3261 - 17.1.1.2 Formal Description
If the client transaction is still in the "Calling" state when timer
B fires, the client transaction SHOULD inform the TU that a timeout
has occurred. The client transaction MUST NOT generate an ACK. The
value of 64*T1 is equal to the amount of time required to send seven
requests in the case of an unreliable transport.
*/
TSIP_TRANSAC(self)->dialog->callback(TSIP_TRANSAC(self)->dialog, tsip_dialog_timedout, TSIP_NULL);
return 0;
}
/* Calling -> (300-699) -> Completed
*/
int tsip_transac_ict_Calling_2_Completed_X_300_to_699(va_list *app)
{
tsip_transac_ict_t *self = va_arg(*app, tsip_transac_ict_t *);
const tsip_response_t *response = va_arg(*app, const tsip_response_t *);
int ret;
/* RFC 3261 - 17.1.1.2 Formal Description
When in either the "Calling" or "Proceeding" states, reception of a
response with status code from 300-699 MUST cause the client
transaction to transition to "Completed". The client transaction
MUST pass the received response up to the TU, and the client
transaction MUST generate an ACK request, even if the transport is
reliable (guidelines for constructing the ACK from the response are
given in Section 17.1.1.3) and then pass the ACK to the transport
layer for transmission. The ACK MUST be sent to the same address,
port, and transport to which the original request was sent.
*/
/* Do not retransmit */
if(!TSIP_TRANSAC(self)->reliable){
TRANSAC_TIMER_CANCEL(A);
}
TRANSAC_TIMER_CANCEL(B); /* Now it's up to the UAS to update the FSM. */
/* RFC 3261 - 17.1.1.2 Formal Description
The client transaction SHOULD start timer D when it enters the
"Completed" state, with a value of at least 32 seconds for unreliable
transports, and a value of zero seconds for reliable transports.
Timer D reflects the amount of time that the server transaction can
remain in the "Completed" state when unreliable transports are used.
This is equal to Timer H in the INVITE server transaction, whose
default is 64*T1. However, the client transaction does not know the
value of T1 in use by the server transaction, so an absolute minimum
of 32s is used instead of basing Timer D on T1.
*/
TRANSAC_ICT_TIMER_SCHEDULE(D); /* timerD already have the right value (0 if reliable and non-zero otherwise) */
/* Send ACK */
ret = tsip_transac_ict_send_ack(response);
/* Pass the response to the dialog. */
TSIP_TRANSAC(self)->dialog->callback(TSIP_TRANSAC(self)->dialog, tsip_dialog_i_msg, response);
return ret;
}
/* Calling -> (1xx) -> Proceeding
*/
int tsip_transac_ict_Calling_2_Proceeding_X_1xx(va_list *app)
{
tsip_transac_ict_t *self = va_arg(*app, tsip_transac_ict_t *);
const tsip_response_t *response = va_arg(*app, const tsip_response_t *);
/* RFC 3261 - 17.1.1.2 Formal Description
If the client transaction receives a provisional response while in
the "Calling" state, it transitions to the "Proceeding" state. In the
"Proceeding" state, the client transaction SHOULD NOT retransmit the
request any longer. Furthermore, the provisional response MUST be
passed to the TU. Any further provisional responses MUST be passed
up to the TU while in the "Proceeding" state.
*/
/* Do not retransmit */
if(!TSIP_TRANSAC(self)->reliable){
TRANSAC_TIMER_CANCEL(A);
}
TRANSAC_TIMER_CANCEL(B); /* Now it's up to the UAS to update the FSM. */
/* Pass the provisional response to the dialog. */
TSIP_TRANSAC(self)->dialog->callback(TSIP_TRANSAC(self)->dialog, tsip_dialog_i_msg, response);
return 0;
}
/* Calling -> (2xx) -> Accepted
*/
int tsip_transac_ict_Calling_2_Accepted_X_2xx(va_list *app)
{
return 0;
}
/* Proceeding -> (1xx) -> Proceeding
*/
int tsip_transac_ict_Proceeding_2_Proceeding_X_1xx(va_list *app)
{
return 0;
}
/* Proceeding -> (300-699) -> Completed
*/
int tsip_transac_ict_Proceeding_2_Completed_X_300_to_699(va_list *app)
{
tsip_transac_ict_t *self = va_arg(*app, tsip_transac_ict_t *);
const tsip_response_t *response = va_arg(*app, const tsip_response_t *);
int ret;
/* RFC 3261 - 17.1.1.2 Formal Description
When in either the "Calling" or "Proceeding" states, reception of a
response with status code from 300-699 MUST cause the client
transaction to transition to "Completed". The client transaction
MUST pass the received response up to the TU, and the client
transaction MUST generate an ACK request, even if the transport is
reliable (guidelines for constructing the ACK from the response are
given in Section 17.1.1.3) and then pass the ACK to the transport
layer for transmission. The ACK MUST be sent to the same address,
port, and transport to which the original request was sent.
*/
/* Do not retransmit */
if(!TSIP_TRANSAC(self)->reliable){
TRANSAC_TIMER_CANCEL(A);
}
TRANSAC_TIMER_CANCEL(B); /* Now it's up to the UAS to update the FSM. */
/* RFC 3261 - 17.1.1.2 Formal Description
The client transaction SHOULD start timer D when it enters the
"Completed" state, with a value of at least 32 seconds for unreliable
transports, and a value of zero seconds for reliable transports.
Timer D reflects the amount of time that the server transaction can
remain in the "Completed" state when unreliable transports are used.
This is equal to Timer H in the INVITE server transaction, whose
default is 64*T1. However, the client transaction does not know the
value of T1 in use by the server transaction, so an absolute minimum
of 32s is used instead of basing Timer D on T1.
*/
TRANSAC_ICT_TIMER_SCHEDULE(D); /* timerD already have the right value (0 if reliable and non-zero otherwise) */
/* Send ACK */
ret = tsip_transac_ict_send_ack(response);
/* Pass the response to the dialog. */
TSIP_TRANSAC(self)->dialog->callback(TSIP_TRANSAC(self)->dialog, tsip_dialog_i_msg, response);
return ret;
}
/* Proceeding -> (2xx) -> Accepted
*/
int tsip_transac_ict_Proceeding_2_Accepted_X_2xx(va_list *app)
{
/* draft-sparks-sip-invfix-02 - 8.5. Pages 134 to 135
........ TO BE CONTINUED
*/
return 0;
}
/* Completed -> (300-699) -> Completed
*/
int tsip_transac_ict_Completed_2_Completed_X_300_to_699(va_list *app)
{
//tsip_transac_ict_t *self = va_arg(*app, tsip_transac_ict_t *);
const tsip_response_t *response = va_arg(*app, const tsip_response_t *);
/* RFC 3261 - 17.1.1.2 Formal Description
Any retransmissions of the final response that are received while in
the "Completed" state MUST cause the ACK to be re-passed to the
transport layer for retransmission, but the newly received response
MUST NOT be passed up to the TU. A retransmission of the response is
defined as any response which would match the same client transaction
based on the rules of Section 17.1.3.
*/
return tsip_transac_ict_send_ack(response);
}
/* Completed -> (timerD) -> Terminated
*/
int tsip_transac_ict_Completed_2_Terminated_X_timerD(va_list *app)
{
/* RFC 3261 - 17.1.1.2 Formal Description
If timer D fires while the client transaction is in the "Completed"
state, the client transaction MUST move to the terminated state.
*/
/* Timers will be canceled by "tsip_transac_ict_OnTerminated" */
return 0;
}
/* Accepted -> (1xx) -> Accepted
*/
int tsip_transac_ict_Accepted_2_Accepted_X_1xx(va_list *app)
{
return 0;
}
/* Accepted -> (timerM) -> Terminated
*/
int tsip_transac_ict_Accepted_2_Terminated_X_timerM(va_list *app)
{
return 0;
}
/* Any -> (Transport Error) -> Terminated
*/
int tsip_transac_ict_Any_2_Terminated_X_transportError(va_list *app)
{
return 0;
}
/* Any -> (Error) -> Terminated
*/
int tsip_transac_ict_Any_2_Terminated_X_Error(va_list *app)
{
return 0;
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// == STATE MACHINE END ==
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++
/* Send ACK message*/
int tsip_transac_ict_send_ack(const tsip_response_t* response)
{
return -1;
}
/*== TERMINATED
*/
int tsip_transac_ict_OnTerminated(tsip_transac_ict_t *self)
{
/* RFC 3261 - 17.1.1.2 Formal Description
The client transaction MUST be destroyed the instant it enters the
"Terminated" state. This is actually necessary to guarantee correct
operation.
*/
/* Cancel timers */
if(!TSIP_TRANSAC(self)->reliable){
TRANSAC_TIMER_CANCEL(A);
}
TRANSAC_TIMER_CANCEL(B);
TRANSAC_TIMER_CANCEL(D);
TRANSAC_TIMER_CANCEL(M);
TSIP_TRANSAC(self)->running = 0;
TSK_DEBUG_INFO("=== ICT terminated ===");
/* Remove (and destroy) the transaction from the layer. */
return tsip_transac_remove(TSIP_TRANSAC(self));
}
//========================================================
// ICT object definition
//
static void* tsip_transac_ict_create(void * self, va_list * app)
{
tsip_transac_ict_t *transac = self;
if(transac)
{
const tsip_stack_handle_t *stack = va_arg(*app, const tsip_stack_handle_t *);
unsigned reliable = va_arg(*app, unsigned);
int32_t cseq_value = va_arg(*app, int32_t);
const char *cseq_method = "INVITE";
const char *callid = va_arg(*app, const char *);
/* create FSM */
transac->fsm = TSK_FSM_CREATE(_fsm_state_Started, _fsm_state_Terminated);
transac->fsm->debug = DEBUG_STATE_MACHINE;
tsk_fsm_set_callback_terminated(transac->fsm, TSK_FSM_ONTERMINATED(tsip_transac_ict_OnTerminated), (const void*)transac);
/* Initialize base class */
tsip_transac_init(TSIP_TRANSAC(transac), stack, tsip_ict, reliable, cseq_value, cseq_method, callid);
/* Initialize ICT object */
tsip_transac_ict_init(transac);
}
return self;
}
static void* tsip_transac_ict_destroy(void * self)
{
tsip_transac_ict_t *transac = self;
if(transac)
{
TSIP_TRANSAC(transac)->running = 0;
TSK_OBJECT_SAFE_FREE(transac->request);
/* DeInitialize base class */
tsip_transac_deinit(TSIP_TRANSAC(transac));
/* FSM */
TSK_OBJECT_SAFE_FREE(transac->fsm);
}
return self;
}
static int tsip_transac_ict_cmp(const tsk_object_t *t1, const tsk_object_t *t2)
{
return tsip_transac_cmp(t1, t2);
}
static const tsk_object_def_t tsip_transac_ict_def_s =
{
sizeof(tsip_transac_ict_t),
tsip_transac_ict_create,
tsip_transac_ict_destroy,
tsip_transac_ict_cmp,
};
const void *tsip_transac_ict_def_t = &tsip_transac_ict_def_s;

View File

@ -131,9 +131,6 @@ _fsm_state_t;
* Callback function called by the transport layer to alert the transaction for incoming messages
* or errors (e.g. transport error).
*
* @author Mamadou
* @date 1/4/2010
*
* @param [in,out] self A pointer to the NIC transaction.
* @param type The event type.
* @param [in,out] msg The incoming message.
@ -204,10 +201,7 @@ int tsip_transac_nict_timer_callback(const tsip_transac_nict_t* self, tsk_timer_
return ret;
}
/**
* @fn int tsip_transac_nict_init(tsip_transac_nict_t *self)
*
* @brief Initializes the transaction.
/** Initializes the transaction.
*
* @author Mamadou
* @date 12/24/2009
@ -226,7 +220,6 @@ int tsip_transac_nict_init(tsip_transac_nict_t *self)
TSK_FSM_ADD_ALWAYS(_fsm_state_Started, _fsm_action_send, _fsm_state_Trying, tsip_transac_nict_Started_2_Trying_X_send, "tsip_transac_nict_Started_2_Trying_X_send"),
// Started -> (Any) -> Started
TSK_FSM_ADD_ALWAYS_NOTHING(_fsm_state_Started, "tsip_transac_nict_Started_2_Started_X_any"),
/*=======================
* === Trying ===
@ -241,7 +234,6 @@ int tsip_transac_nict_init(tsip_transac_nict_t *self)
TSK_FSM_ADD_ALWAYS(_fsm_state_Trying, _fsm_action_1xx, _fsm_state_Proceeding, tsip_transac_nict_Trying_2_Proceedding_X_1xx, "tsip_transac_nict_Trying_2_Proceedding_X_1xx"),
// Trying -> (200 to 699) -> Completed
TSK_FSM_ADD_ALWAYS(_fsm_state_Trying, _fsm_action_200_to_699, _fsm_state_Completed, tsip_transac_nict_Trying_2_Completed_X_200_to_699, "tsip_transac_nict_Trying_2_Completed_X_200_to_699"),
/*=======================
* === Proceeding ===
@ -256,7 +248,6 @@ int tsip_transac_nict_init(tsip_transac_nict_t *self)
TSK_FSM_ADD_ALWAYS(_fsm_state_Proceeding, _fsm_action_1xx, _fsm_state_Proceeding, tsip_transac_nict_Proceeding_2_Proceeding_X_1xx, "tsip_transac_nict_Proceeding_2_Proceeding_X_1xx"),
// Proceeding -> (200 to 699) -> Completed
TSK_FSM_ADD_ALWAYS(_fsm_state_Proceeding, _fsm_action_200_to_699, _fsm_state_Completed, tsip_transac_nict_Proceeding_2_Completed_X_200_to_699, "tsip_transac_nict_Proceeding_2_Completed_X_200_to_699"),
/*=======================
* === Completed ===
@ -264,7 +255,6 @@ int tsip_transac_nict_init(tsip_transac_nict_t *self)
// Completed -> (timer K) -> Terminated
TSK_FSM_ADD_ALWAYS(_fsm_state_Completed, _fsm_action_timerK, _fsm_state_Terminated, tsip_transac_nict_Completed_2_Terminated_X_timerK, "tsip_transac_nict_Completed_2_Terminated_X_timerK"),
/*=======================
* === Any ===
*/
@ -277,17 +267,18 @@ int tsip_transac_nict_init(tsip_transac_nict_t *self)
TSK_FSM_ADD_NULL());
/* Set callback function to call when new messages arrive or errors happen in
the transport layer.
the transport layer.
*/
TSIP_TRANSAC(self)->callback = TSIP_TRANSAC_EVENT_CALLBACK(tsip_transac_nict_event_callback);
self->timerE.id = TSK_INVALID_TIMER_ID;
self->timerF.id = TSK_INVALID_TIMER_ID;
self->timerK.id = TSK_INVALID_TIMER_ID;
self->timerE.timeout = TSIP_TIMER_GET(E);
self->timerF.timeout = TSIP_TIMER_GET(F);
self->timerK.timeout = TSIP_TRANSAC(self)->reliable ? 0 : TSIP_TIMER_GET(K); /* RFC 3261 - 17.1.2.2*/
/* Timers */
self->timerE.id = TSK_INVALID_TIMER_ID;
self->timerF.id = TSK_INVALID_TIMER_ID;
self->timerK.id = TSK_INVALID_TIMER_ID;
self->timerE.timeout = TSIP_TIMER_GET(E);
self->timerF.timeout = TSIP_TIMER_GET(F);
self->timerK.timeout = TSIP_TRANSAC(self)->reliable ? 0 : TSIP_TIMER_GET(K); /* RFC 3261 - 17.1.2.2*/
return 0;
}
@ -307,7 +298,7 @@ int tsip_transac_nict_start(tsip_transac_nict_t *self, const tsip_request_t* req
if(self && request && !TSIP_TRANSAC(self)->running)
{
/* Add branch to the new client transaction. */
TSIP_TRANSAC(self)->branch = tsk_strdup(TSIP_TRANSAC_MAGIC_COOKIE);
if((TSIP_TRANSAC(self)->branch = tsk_strdup(TSIP_TRANSAC_MAGIC_COOKIE)))
{
tsk_istr_t branch;
tsk_strrandom(&branch);
@ -339,7 +330,7 @@ int tsip_transac_nict_start(tsip_transac_nict_t *self, const tsip_request_t* req
int tsip_transac_nict_Started_2_Trying_X_send(va_list *app)
{
tsip_transac_nict_t *self = va_arg(*app, tsip_transac_nict_t *);
const tsip_message_t *message = va_arg(*app, const tsip_message_t *);
//const tsip_message_t *message = va_arg(*app, const tsip_message_t *);
//== Send the request
tsip_transac_send(TSIP_TRANSAC(self), TSIP_TRANSAC(self)->branch, TSIP_MESSAGE(self->request));
@ -355,8 +346,7 @@ int tsip_transac_nict_Started_2_Trying_X_send(va_list *app)
If an unreliable transport is in use, the client transaction MUST set timer
E to fire in T1 seconds.
*/
if(!TSIP_TRANSAC(self)->reliable)
{
if(!TSIP_TRANSAC(self)->reliable){
TRANSAC_NICT_TIMER_SCHEDULE(E);
}
@ -401,7 +391,7 @@ int tsip_transac_nict_Trying_2_Terminated_X_timerF(va_list *app)
/* Timers will be canceled by "tsip_transac_nict_OnTerminated" */
TSIP_TRANSAC(self)->dialog->callback(TSIP_TRANSAC(self)->dialog, tsip_dialog_transport_error, 0);
TSIP_TRANSAC(self)->dialog->callback(TSIP_TRANSAC(self)->dialog, tsip_dialog_timedout, TSIP_NULL);
return 0;
}
@ -415,7 +405,7 @@ int tsip_transac_nict_Trying_2_Terminated_X_transportError(va_list *app)
/* Timers will be canceled by "tsip_transac_nict_OnTerminated" */
TSIP_TRANSAC(self)->dialog->callback(TSIP_TRANSAC(self)->dialog, tsip_dialog_transport_error, 0);
TSIP_TRANSAC(self)->dialog->callback(TSIP_TRANSAC(self)->dialog, tsip_dialog_transport_error, TSIP_NULL);
return 0;
}
@ -434,12 +424,12 @@ int tsip_transac_nict_Trying_2_Proceedding_X_1xx(va_list *app)
*/
/* Cancel timers */
if(!TSIP_TRANSAC(self)->reliable)
{
if(!TSIP_TRANSAC(self)->reliable){
TRANSAC_TIMER_CANCEL(E);
}
TRANSAC_TIMER_CANCEL(F);
TRANSAC_TIMER_CANCEL(F); /* Now it's up to the UAS to update the FSM. */
/* Pass the provisional response to the dialog. */
TSIP_TRANSAC(self)->dialog->callback(TSIP_TRANSAC(self)->dialog, tsip_dialog_i_msg, message);
return 0;
@ -460,8 +450,7 @@ int tsip_transac_nict_Trying_2_Completed_X_200_to_699(va_list *app)
If Timer K fires while in this state (Completed), the client transaction MUST transition to the "Terminated" state.
*/
if(!TSIP_TRANSAC(self)->reliable)
{
if(!TSIP_TRANSAC(self)->reliable){
TRANSAC_TIMER_CANCEL(E);
}
TRANSAC_TIMER_CANCEL(F);
@ -479,7 +468,7 @@ int tsip_transac_nict_Trying_2_Completed_X_200_to_699(va_list *app)
int tsip_transac_nict_Proceeding_2_Proceeding_X_timerE(va_list *app)
{
tsip_transac_nict_t *self = va_arg(*app, tsip_transac_nict_t *);
const tsip_message_t *message = va_arg(*app, const tsip_message_t *);
//const tsip_message_t *message = va_arg(*app, const tsip_message_t *);
//== Send the request
tsip_transac_send(TSIP_TRANSAC(self), TSIP_TRANSAC(self)->branch, self->request);
@ -500,7 +489,7 @@ int tsip_transac_nict_Proceeding_2_Proceeding_X_timerE(va_list *app)
int tsip_transac_nict_Proceeding_2_Terminated_X_timerF(va_list *app)
{
tsip_transac_nict_t *self = va_arg(*app, tsip_transac_nict_t *);
const tsip_message_t *message = va_arg(*app, const tsip_message_t *);
//const tsip_message_t *message = va_arg(*app, const tsip_message_t *);
/* RFC 3261 - 17.1.2.2
If timer F fires while in the "Proceeding" state, the TU MUST be informed of a timeout, and the
@ -534,8 +523,7 @@ int tsip_transac_nict_Proceeding_2_Proceeding_X_1xx(va_list *app)
tsip_transac_nict_t *self = va_arg(*app, tsip_transac_nict_t *);
const tsip_message_t *message = va_arg(*app, const tsip_message_t *);
if(!TSIP_TRANSAC(self)->reliable)
{
if(!TSIP_TRANSAC(self)->reliable){
TRANSAC_TIMER_CANCEL(E);
}
TSIP_TRANSAC(self)->dialog->callback(TSIP_TRANSAC(self)->dialog, tsip_dialog_i_msg, message);
@ -568,8 +556,7 @@ int tsip_transac_nict_Proceeding_2_Completed_X_200_to_699(va_list *app)
The default value of T4 is 5s.
*/
if(!TSIP_TRANSAC(self)->reliable)
{
if(!TSIP_TRANSAC(self)->reliable){
TRANSAC_TIMER_CANCEL(E);
}
@ -585,8 +572,8 @@ int tsip_transac_nict_Proceeding_2_Completed_X_200_to_699(va_list *app)
*/
int tsip_transac_nict_Completed_2_Terminated_X_timerK(va_list *app)
{
tsip_transac_nict_t *self = va_arg(*app, tsip_transac_nict_t *);
const tsip_message_t *message = va_arg(*app, const tsip_message_t *);
//tsip_transac_nict_t *self = va_arg(*app, tsip_transac_nict_t *);
//const tsip_message_t *message = va_arg(*app, const tsip_message_t *);
/* RFC 3261 - 17.1.2.2
If Timer K fires while in this state (Completed), the client transaction
@ -717,7 +704,7 @@ static void* tsip_transac_nict_destroy(void * self)
return self;
}
static int tsip_transac_nict_cmp(const void *t1, const void *t2)
static int tsip_transac_nict_cmp(const tsk_object_t *t1, const tsk_object_t *t2)
{
return tsip_transac_cmp(t1, t2);
}

View File

@ -198,7 +198,6 @@ int tsip_transac_nist_init(tsip_transac_nist_t *self)
TSK_FSM_ADD_ALWAYS(_fsm_state_Started, _fsm_action_request, _fsm_state_Trying, tsip_transac_nist_Started_2_Trying_X_request, "tsip_transac_nist_Started_2_Trying_X_request"),
// Started -> (Any) -> Started
TSK_FSM_ADD_ALWAYS_NOTHING(_fsm_state_Started, "tsip_transac_nist_Started_2_Started_X_any"),
/*=======================
* === Trying ===
@ -208,7 +207,6 @@ int tsip_transac_nist_init(tsip_transac_nist_t *self)
// Trying -> (send 200 to 699) -> Completed
TSK_FSM_ADD_ALWAYS(_fsm_state_Trying, _fsm_action_send_200_to_699, _fsm_state_Completed, tsip_transac_nist_Trying_2_Completed_X_send_200_to_699, "tsip_transac_nist_Trying_2_Completed_X_send_200_to_699"),
/*=======================
* === Proceeding ===
*/
@ -219,7 +217,6 @@ int tsip_transac_nist_init(tsip_transac_nist_t *self)
// Proceeding -> (receive request) -> Proceeding
TSK_FSM_ADD_ALWAYS(_fsm_state_Proceeding, _fsm_action_request, _fsm_state_Proceeding, tsip_transac_nist_Proceeding_2_Proceeding_X_request, "tsip_transac_nist_Proceeding_2_Proceeding_X_request"),
/*=======================
* === Completed ===
*/
@ -227,7 +224,6 @@ int tsip_transac_nist_init(tsip_transac_nist_t *self)
TSK_FSM_ADD_ALWAYS(_fsm_state_Completed, _fsm_action_request, _fsm_state_Completed, tsip_transac_nist_Completed_2_Completed_X_request, "tsip_transac_nist_Completed_2_Completed_X_request"),
// Completed -> (timer J) -> Terminated
TSK_FSM_ADD_ALWAYS(_fsm_state_Completed, _fsm_action_timerJ, _fsm_state_Terminated, tsip_transac_nist_Completed_2_Terminated_X_tirmerJ, "tsip_transac_nist_Completed_2_Terminated_X_tirmerJ"),
/*=======================
* === Any ===
@ -563,7 +559,7 @@ static void* tsip_transac_nist_destroy(void * self)
return self;
}
static int tsip_transac_nist_cmp(const void *t1, const void *t2)
static int tsip_transac_nist_cmp(const tsk_object_t *t1, const tsk_object_t *t2)
{
return tsip_transac_cmp(t1, t2);
}

View File

@ -143,7 +143,7 @@ size_t tsip_transport_send(const tsip_transport_t* self, const char *branch, tsi
tsk_buffer_t *buffer = 0;
/* Add Via */
if(TSIP_MESSAGE_IS_REQUEST(msg) && msg->request_type != tsip_CANCEL){
if(TSIP_MESSAGE_IS_REQUEST(msg) && !TSIP_REQUEST_IS_CANCEL(msg)){
tsip_transport_addvia(self, branch, msg);
tsip_transport_msg_update(self, msg);
}

View File

@ -243,7 +243,7 @@ int tsip_transport_ipsec_updateMSG(tsip_transport_ipsec_t* self, tsip_message_t
goto bail;
}
asso = (self->asso_temporary && msg->request_type == tsip_REGISTER) ? self->asso_temporary : self->asso_active;
asso = (self->asso_temporary && TSIP_REQUEST_IS_REGISTER(msg)) ? self->asso_temporary : self->asso_active;
if(!asso || !asso->ctx){
TSK_DEBUG_ERROR("No IPSec association found.");
ret = -2;

View File

@ -84,6 +84,8 @@
//const char *timerI = "timerI";
//const char *timerJ = "timerJ";
//const char *timerK = "timerK";
//const char *timerL = "timerL";
//const char *timerM = "timerM";
static uint32_t T1 = TIMER_T1;
@ -100,150 +102,139 @@ static uint32_t H = 64*TIMER_T1;
static uint32_t I = TIMER_T4;
static uint32_t J = 64*TIMER_T1;
static uint32_t K = TIMER_T4;
static uint32_t L = 64*TIMER_T1; // draft-sparks-sip-invfix
static uint32_t M = 64*TIMER_T1; // draft-sparks-sip-invfix
void tsip_timers_setT1(uint32_t t1)
{
void tsip_timers_setT1(uint32_t t1){
T1 = t1;
A = E = G = T1;
B = F = H = J = (T1*64);
}
void tsip_timers_setT2(uint32_t t2)
{
void tsip_timers_setT2(uint32_t t2){
T2 = t2;
}
void tsip_timers_setT4(uint32_t t4)
{
void tsip_timers_setT4(uint32_t t4){
T4 = t4;
I = K = T4;
}
void tsip_timers_setA(uint32_t a)
{
void tsip_timers_setA(uint32_t a){
A = a;
}
void tsip_timers_setB(uint32_t b)
{
void tsip_timers_setB(uint32_t b){
B = b;
}
void tsip_timers_setc(uint32_t c)
{
void tsip_timers_setc(uint32_t c){
C = c;
}
void tsip_timers_setD(uint32_t d)
{
void tsip_timers_setD(uint32_t d){
D = d;
}
void tsip_timers_setE(uint32_t e)
{
void tsip_timers_setE(uint32_t e){
E = e;
}
void tsip_timers_setF(uint32_t f)
{
void tsip_timers_setF(uint32_t f){
F = f;
}
void tsip_timers_setG(uint32_t g)
{
void tsip_timers_setG(uint32_t g){
G = g;
}
void tsip_timers_setH(uint32_t h)
{
void tsip_timers_setH(uint32_t h){
H = h;
}
void tsip_timers_setI(uint32_t i)
{
void tsip_timers_setI(uint32_t i){
I = i;
}
void tsip_timers_setJ(uint32_t j)
{
void tsip_timers_setJ(uint32_t j){
J = j;
}
void tsip_timers_setK(uint32_t k)
{
void tsip_timers_setK(uint32_t k){
K = k;
}
void tsip_timers_setL(uint32_t l){
L = l;
}
uint32_t tsip_timers_getT1()
{
void tsip_timers_setM(uint32_t m){
M = m;
}
uint32_t tsip_timers_getT1(){
return T1;
}
uint32_t tsip_timers_getT2()
{
uint32_t tsip_timers_getT2(){
return T2;
}
uint32_t tsip_timers_getT4()
{
uint32_t tsip_timers_getT4(){
return T4;
}
uint32_t tsip_timers_getA()
{
uint32_t tsip_timers_getA(){
return A;
}
uint32_t tsip_timers_getB()
{
uint32_t tsip_timers_getB(){
return B;
}
uint32_t tsip_timers_getC()
{
uint32_t tsip_timers_getC(){
return C;
}
uint32_t tsip_timers_getD()
{
uint32_t tsip_timers_getD(){
return D;
}
uint32_t tsip_timers_getE()
{
uint32_t tsip_timers_getE(){
return E;
}
uint32_t tsip_timers_getF()
{
uint32_t tsip_timers_getF(){
return F;
}
uint32_t tsip_timers_getG()
{
uint32_t tsip_timers_getG(){
return G;
}
uint32_t tsip_timers_getH()
{
uint32_t tsip_timers_getH(){
return H;
}
uint32_t tsip_timers_getI()
{
uint32_t tsip_timers_getI(){
return I;
}
uint32_t tsip_timers_getJ()
{
uint32_t tsip_timers_getJ(){
return J;
}
uint32_t tsip_timers_getK()
{
uint32_t tsip_timers_getK(){
return K;
}
uint32_t tsip_timers_getL(){
return L;
}
uint32_t tsip_timers_getM(){
return M;
}

View File

@ -226,8 +226,8 @@ int test_stack_callback(const tsip_event_t *sipevent)
void test_stack()
{
//#define DOMAIN "ericsson.com"
#define DOMAIN "micromethod.com"
#define DOMAIN "ericsson.com"
//#define DOMAIN "micromethod.com"
//#define DOMAIN "ims.inexbee.com"
//#define DOMAIN "sip2sip.info"
@ -248,7 +248,7 @@ void test_stack()
TSIP_STACK_SET_NETINFO("ADSL;utran-cell-id-3gpp=00000000"),
TSIP_STACK_SET_PRIVACY("header;id"),
*/
/*
tsip_stack_handle_t *stack = tsip_stack_create(test_stack_callback,
TSIP_STACK_SET_DISPLAY_NAME("Mamadou"),
TSIP_STACK_SET_PUBLIC_IDENTITY("sip:mamadou@"DOMAIN),
@ -257,7 +257,7 @@ void test_stack()
TSIP_STACK_SET_REALM("sip:"DOMAIN), // FIXME: without sip:
TSIP_STACK_SET_LOCAL_IP(LOCAL_IP),
//TSIP_STACK_SET_DISCOVERY_NAPTR(1),
TSIP_STACK_SET_PROXY_CSCF("192.168.0.11", "udp", 0),
TSIP_STACK_SET_PROXY_CSCF("192.168.0.14", "udp", 0),
//TSIP_STACK_SET_PROXY_CSCF("192.168.0.15", "udp", 0),
TSIP_STACK_SET_PROXY_CSCF_PORT(5081),
//TSIP_STACK_SET_SECAGREE_IPSEC("hmac-md5-96", "null", "trans", "esp"),
@ -265,7 +265,7 @@ void test_stack()
TSIP_STACK_SET_DEVICE_ID("dd1289fa-c3d7-47bd-a40d-f1f1b2cc5ffc"),
TSIP_STACK_SET_NETINFO("ADSL;utran-cell-id-3gpp=00000000"),
TSIP_STACK_SET_PRIVACY("header;id"),
*/
/*
tsip_stack_handle_t *stack = tsip_stack_create(test_stack_callback,
TSIP_STACK_SET_DISPLAY_NAME("Mamadou"),
@ -285,7 +285,7 @@ void test_stack()
TSIP_STACK_SET_NETINFO("ADSL;utran-cell-id-3gpp=00000000"),
TSIP_STACK_SET_PRIVACY("header;id"),
*/
/*
tsip_stack_handle_t *stack = tsip_stack_create(test_stack_callback,
TSIP_STACK_SET_DISPLAY_NAME("Mamadou"),
TSIP_STACK_SET_PUBLIC_IDENTITY("sip:mamadou@"DOMAIN),
@ -302,6 +302,8 @@ void test_stack()
TSIP_STACK_SET_DEVICE_ID("dd1289fa-c3d7-47bd-a40d-f1f1b2cc5ffc"),
TSIP_STACK_SET_NETINFO("ADSL;utran-cell-id-3gpp=00000000"),
TSIP_STACK_SET_PRIVACY("header;id"),
*/
TSIP_STACK_SET_NULL());