summaryrefslogtreecommitdiffstats
path: root/tinySIP/src/transactions
diff options
context:
space:
mode:
Diffstat (limited to 'tinySIP/src/transactions')
-rwxr-xr-xtinySIP/src/transactions/tsip_transac.c340
-rwxr-xr-xtinySIP/src/transactions/tsip_transac_ict.c1180
-rwxr-xr-xtinySIP/src/transactions/tsip_transac_ist.c1008
-rwxr-xr-xtinySIP/src/transactions/tsip_transac_layer.c472
-rwxr-xr-xtinySIP/src/transactions/tsip_transac_nict.c806
-rwxr-xr-xtinySIP/src/transactions/tsip_transac_nist.c611
6 files changed, 2186 insertions, 2231 deletions
diff --git a/tinySIP/src/transactions/tsip_transac.c b/tinySIP/src/transactions/tsip_transac.c
index 1ecac59..6498f51 100755
--- a/tinySIP/src/transactions/tsip_transac.c
+++ b/tinySIP/src/transactions/tsip_transac.c
@@ -2,19 +2,19 @@
* Copyright (C) 2010-2011 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -43,232 +43,226 @@
static tsk_object_t* tsip_transac_dst_ctor(tsk_object_t * _self, va_list * app)
{
- tsip_transac_dst_t *dst = _self;
- if(dst){
-
- }
- return _self;
+ tsip_transac_dst_t *dst = _self;
+ if(dst) {
+
+ }
+ return _self;
}
static tsk_object_t* tsip_transac_dst_dtor(tsk_object_t * _self)
-{
- tsip_transac_dst_t *dst = _self;
- if(dst){
- TSK_OBJECT_SAFE_FREE(dst->stack);
- switch(dst->type){
- case tsip_transac_dst_type_dialog:
- {
- TSK_OBJECT_SAFE_FREE(dst->dialog.dlg);
- break;
- }
- case tsip_transac_dst_type_net:
- {
- break;
- }
- }
- }
- return _self;
-}
-static const tsk_object_def_t tsip_transac_dst_def_s =
{
- sizeof(tsip_transac_dst_t),
- tsip_transac_dst_ctor,
- tsip_transac_dst_dtor,
- tsk_null,
+ tsip_transac_dst_t *dst = _self;
+ if(dst) {
+ TSK_OBJECT_SAFE_FREE(dst->stack);
+ switch(dst->type) {
+ case tsip_transac_dst_type_dialog: {
+ TSK_OBJECT_SAFE_FREE(dst->dialog.dlg);
+ break;
+ }
+ case tsip_transac_dst_type_net: {
+ break;
+ }
+ }
+ }
+ return _self;
+}
+static const tsk_object_def_t tsip_transac_dst_def_s = {
+ sizeof(tsip_transac_dst_t),
+ tsip_transac_dst_ctor,
+ tsip_transac_dst_dtor,
+ tsk_null,
};
const tsk_object_def_t *tsip_transac_dst_def_t = &tsip_transac_dst_def_s;
static struct tsip_transac_dst_s* tsip_transac_dst_create(tsip_transac_dst_type_t type, struct tsip_stack_s* stack)
{
- struct tsip_transac_dst_s* dst = tsk_object_new(tsip_transac_dst_def_t);
- if(dst){
- dst->type = type;
- dst->stack = tsk_object_ref(stack);
- }
- return dst;
+ struct tsip_transac_dst_s* dst = tsk_object_new(tsip_transac_dst_def_t);
+ if(dst) {
+ dst->type = type;
+ dst->stack = tsk_object_ref(stack);
+ }
+ return dst;
}
struct tsip_transac_dst_s* tsip_transac_dst_dialog_create(tsip_dialog_t *dlg)
{
- struct tsip_transac_dst_s* dst;
- if((dst = tsip_transac_dst_create(tsip_transac_dst_type_dialog, TSIP_DIALOG_GET_STACK(dlg)))){
- dst->dialog.dlg = tsk_object_ref(dlg);
- }
- return dst;
+ struct tsip_transac_dst_s* dst;
+ if((dst = tsip_transac_dst_create(tsip_transac_dst_type_dialog, TSIP_DIALOG_GET_STACK(dlg)))) {
+ dst->dialog.dlg = tsk_object_ref(dlg);
+ }
+ return dst;
}
struct tsip_transac_dst_s* tsip_transac_dst_net_create(struct tsip_stack_s* stack)
{
- struct tsip_transac_dst_s* dst;
- if((dst = tsip_transac_dst_create(tsip_transac_dst_type_net, stack))){
- }
- return dst;
+ struct tsip_transac_dst_s* dst;
+ if((dst = tsip_transac_dst_create(tsip_transac_dst_type_net, stack))) {
+ }
+ return dst;
}
static int tsip_transac_dst_deliver(struct tsip_transac_dst_s* self, tsip_dialog_event_type_t event_type, const tsip_message_t *msg)
{
- if(!self){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
-
- switch(self->type){
- case tsip_transac_dst_type_dialog:
- {
- return self->dialog.dlg->callback(
- self->dialog.dlg,
- event_type,
- msg
- );
- }
- case tsip_transac_dst_type_net:
- {
- if(!msg){
- TSK_DEBUG_ERROR("Message is null");
- return -1;
- }
-
- // all messages coming from WebSocket transport have to be updated (AoR, Via...) before network delivering
- // all other messages MUST not unless specified from the dialog layer
- TSIP_MESSAGE(msg)->update |= (TNET_SOCKET_TYPE_IS_WS(msg->src_net_type) || TNET_SOCKET_TYPE_IS_WSS(msg->src_net_type));
-
- return tsip_transport_layer_send(
- self->stack->layer_transport,
- msg->firstVia ? msg->firstVia->branch : tsk_null,
- TSIP_MESSAGE(msg)
- );
- }
- default:
- {
- TSK_DEBUG_ERROR("Unexpected code called");
- return -2;
- }
- }
+ if(!self) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+
+ switch(self->type) {
+ case tsip_transac_dst_type_dialog: {
+ return self->dialog.dlg->callback(
+ self->dialog.dlg,
+ event_type,
+ msg
+ );
+ }
+ case tsip_transac_dst_type_net: {
+ if(!msg) {
+ TSK_DEBUG_ERROR("Message is null");
+ return -1;
+ }
+
+ // all messages coming from WebSocket transport have to be updated (AoR, Via...) before network delivering
+ // all other messages MUST not unless specified from the dialog layer
+ TSIP_MESSAGE(msg)->update |= (TNET_SOCKET_TYPE_IS_WS(msg->src_net_type) || TNET_SOCKET_TYPE_IS_WSS(msg->src_net_type));
+
+ return tsip_transport_layer_send(
+ self->stack->layer_transport,
+ msg->firstVia ? msg->firstVia->branch : tsk_null,
+ TSIP_MESSAGE(msg)
+ );
+ }
+ default: {
+ TSK_DEBUG_ERROR("Unexpected code called");
+ return -2;
+ }
+ }
}
int tsip_transac_init(tsip_transac_t *self, tsip_transac_type_t type, int32_t cseq_value, const char* cseq_method, const char* callid, struct tsip_transac_dst_s* dst, tsk_fsm_state_id curr, tsk_fsm_state_id term)
{
- if(self && !self->initialized){
- self->type = type;
- self->cseq_value = cseq_value;
- tsk_strupdate(&self->cseq_method, cseq_method);
- tsk_strupdate(&self->callid, callid);
- self->dst = tsk_object_ref(dst);
-
- /* FSM */
- self->fsm = tsk_fsm_create(curr, term);
-
- self->initialized = tsk_true;
-
- return 0;
- }
- return -1;
+ if(self && !self->initialized) {
+ self->type = type;
+ self->cseq_value = cseq_value;
+ tsk_strupdate(&self->cseq_method, cseq_method);
+ tsk_strupdate(&self->callid, callid);
+ self->dst = tsk_object_ref(dst);
+
+ /* FSM */
+ self->fsm = tsk_fsm_create(curr, term);
+
+ self->initialized = tsk_true;
+
+ return 0;
+ }
+ return -1;
}
int tsip_transac_deinit(tsip_transac_t *self)
{
- if(self && self->initialized){
- /* FSM */
- TSK_OBJECT_SAFE_FREE(self->fsm);
-
- TSK_FREE(self->branch);
- TSK_FREE(self->cseq_method);
- TSK_FREE(self->callid);
- TSK_OBJECT_SAFE_FREE(self->dst);
-
- self->initialized = tsk_false;
-
- return 0;
- }
- return -1;
+ if(self && self->initialized) {
+ /* FSM */
+ TSK_OBJECT_SAFE_FREE(self->fsm);
+
+ TSK_FREE(self->branch);
+ TSK_FREE(self->cseq_method);
+ TSK_FREE(self->callid);
+ TSK_OBJECT_SAFE_FREE(self->dst);
+
+ self->initialized = tsk_false;
+
+ return 0;
+ }
+ return -1;
}
int tsip_transac_start(tsip_transac_t *self, const tsip_request_t* request)
{
- if(!self){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
-
- switch(self->type){
- case tsip_transac_type_nist:{
- return tsip_transac_nist_start(TSIP_TRANSAC_NIST(self), request);
- }
- case tsip_transac_type_ist:{
- return tsip_transac_ist_start(TSIP_TRANSAC_IST(self), request);
- }
- case tsip_transac_type_nict:{
- return tsip_transac_nict_start(TSIP_TRANSAC_NICT(self), request);
- }
- case tsip_transac_type_ict:{
- return tsip_transac_ict_start(TSIP_TRANSAC_ICT(self), request);
- }
- }
-
- TSK_DEBUG_ERROR("Unexpected code called");
- return -2;
+ if(!self) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+
+ switch(self->type) {
+ case tsip_transac_type_nist: {
+ return tsip_transac_nist_start(TSIP_TRANSAC_NIST(self), request);
+ }
+ case tsip_transac_type_ist: {
+ return tsip_transac_ist_start(TSIP_TRANSAC_IST(self), request);
+ }
+ case tsip_transac_type_nict: {
+ return tsip_transac_nict_start(TSIP_TRANSAC_NICT(self), request);
+ }
+ case tsip_transac_type_ict: {
+ return tsip_transac_ict_start(TSIP_TRANSAC_ICT(self), request);
+ }
+ }
+
+ TSK_DEBUG_ERROR("Unexpected code called");
+ return -2;
}
// deliver the message to the destination (e.g. local dialog)
int tsip_transac_deliver(tsip_transac_t* self, tsip_dialog_event_type_t event_type, const tsip_message_t *msg)
{
- if(!self){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- return tsip_transac_dst_deliver(self->dst, event_type, msg);
+ if(!self) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ return tsip_transac_dst_deliver(self->dst, event_type, msg);
}
// send the message over the network
int tsip_transac_send(tsip_transac_t *self, const char *branch, tsip_message_t *msg)
{
- if(self && TSIP_TRANSAC_GET_STACK(self)->layer_transport && msg){
- const struct tsip_ssession_s* ss = TSIP_TRANSAC_GET_SESSION(self);
- if(ss){
- // set SigComp identifier as the message is directly sent to the transport layer
- tsk_strupdate(&msg->sigcomp_id, ss->sigcomp_id);
- }
- return tsip_transport_layer_send(TSIP_TRANSAC_GET_STACK(self)->layer_transport, branch, TSIP_MESSAGE(msg));
- }
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
+ if(self && TSIP_TRANSAC_GET_STACK(self)->layer_transport && msg) {
+ const struct tsip_ssession_s* ss = TSIP_TRANSAC_GET_SESSION(self);
+ if(ss) {
+ // set SigComp identifier as the message is directly sent to the transport layer
+ tsk_strupdate(&msg->sigcomp_id, ss->sigcomp_id);
+ }
+ return tsip_transport_layer_send(TSIP_TRANSAC_GET_STACK(self)->layer_transport, branch, TSIP_MESSAGE(msg));
+ }
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
}
int tsip_transac_cmp(const tsip_transac_t *t1, const tsip_transac_t *t2)
{
- if(t1 && t2){
- if(tsk_strequals(t1->branch, t2->branch) && tsk_strequals(t1->cseq_method, t2->cseq_method)){
- return 0;
- }
- }
- return -1;
+ if(t1 && t2) {
+ if(tsk_strequals(t1->branch, t2->branch) && tsk_strequals(t1->cseq_method, t2->cseq_method)) {
+ return 0;
+ }
+ }
+ return -1;
}
int tsip_transac_remove(const tsip_transac_t* self)
{
- int ret;
- tsip_transac_t* safe_copy;
-
- safe_copy = (tsip_transac_t*)tsk_object_ref(TSK_OBJECT(self));
- ret = tsip_transac_layer_remove(TSIP_TRANSAC_GET_STACK(self)->layer_transac, safe_copy);
- tsk_object_unref(safe_copy);
-
- return ret;
+ int ret;
+ tsip_transac_t* safe_copy;
+
+ safe_copy = (tsip_transac_t*)tsk_object_ref(TSK_OBJECT(self));
+ ret = tsip_transac_layer_remove(TSIP_TRANSAC_GET_STACK(self)->layer_transac, safe_copy);
+ tsk_object_unref(safe_copy);
+
+ return ret;
}
int tsip_transac_fsm_act(tsip_transac_t* self, tsk_fsm_action_id action_id, const tsip_message_t* message)
{
- int ret;
- tsip_transac_t* safe_copy;
+ int ret;
+ tsip_transac_t* safe_copy;
- if(!self || !self->fsm){
- TSK_DEBUG_WARN("Invalid parameter.");
- return -1;
- }
+ if(!self || !self->fsm) {
+ TSK_DEBUG_WARN("Invalid parameter.");
+ return -1;
+ }
- safe_copy = tsk_object_ref(TSK_OBJECT(self));
- ret = tsk_fsm_act(self->fsm, action_id, safe_copy, message, self, message);
- tsk_object_unref(safe_copy);
+ safe_copy = tsk_object_ref(TSK_OBJECT(self));
+ ret = tsk_fsm_act(self->fsm, action_id, safe_copy, message, self, message);
+ tsk_object_unref(safe_copy);
- return ret;
+ return ret;
}
diff --git a/tinySIP/src/transactions/tsip_transac_ict.c b/tinySIP/src/transactions/tsip_transac_ict.c
index 8678851..c2b9b13 100755
--- a/tinySIP/src/transactions/tsip_transac_ict.c
+++ b/tinySIP/src/transactions/tsip_transac_ict.c
@@ -2,19 +2,19 @@
* Copyright (C) 2010-2011 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -111,32 +111,30 @@ int tsip_transac_ict_Any_2_Terminated_X_cancel(va_list *app); /* doubango-specif
/* ======================== conds ======================== */
/* ======================== actions ======================== */
-typedef enum _fsm_action_e
-{
- _fsm_action_cancel = tsip_atype_cancel,
-
- _fsm_action_send = 0xFF,
- _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,
+typedef enum _fsm_action_e {
+ _fsm_action_cancel = tsip_atype_cancel,
+
+ _fsm_action_send = 0xFF,
+ _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
+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;
@@ -145,88 +143,84 @@ _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] 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.
+ * @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)
-{
- /* draft-sparks-sip-invfix-03 - 7.2. UAC Impacts
- Any response received which does not match an existing client transaction state machine is simply dropped.
- */
- switch(type){
-
- case tsip_transac_incoming_msg:
- {
- if(msg)
- {
- if(TSIP_MESSAGE_IS_RESPONSE(msg)){
- if(TSIP_RESPONSE_IS_1XX(msg)){
- return tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_1xx, msg);
- }
- else if(TSIP_RESPONSE_IS_2XX(msg)){
- return tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_2xx, msg);
- }
- else if(TSIP_RESPONSE_IS_3456(msg)){
- return tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_300_to_699, msg);
- }
- else{
- TSK_DEBUG_WARN("Not supported status code: %d", TSIP_RESPONSE_CODE(msg));
- return 0;
- }
- }
- // any other response have to be delivered if dst_type is 'network'
- if(TSIP_TRANSAC(self)->dst->type == tsip_transac_dst_type_net){
- return tsip_transac_deliver(TSIP_TRANSAC(self), tsip_transac_incoming_msg, msg);
- }
- }
- break;
- }
-
- case tsip_transac_canceled:
- case tsip_transac_terminated:
- case tsip_transac_timedout:
- break;
-
- case tsip_transac_error:
- {
- return tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_error, msg);
- }
-
- case tsip_transac_transport_error:
- {
- return tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_transporterror, msg);
- }
-
- default: break;
- }
-
- return 0;
+{
+ /* draft-sparks-sip-invfix-03 - 7.2. UAC Impacts
+ Any response received which does not match an existing client transaction state machine is simply dropped.
+ */
+ switch(type) {
+
+ case tsip_transac_incoming_msg: {
+ if(msg) {
+ if(TSIP_MESSAGE_IS_RESPONSE(msg)) {
+ if(TSIP_RESPONSE_IS_1XX(msg)) {
+ return tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_1xx, msg);
+ }
+ else if(TSIP_RESPONSE_IS_2XX(msg)) {
+ return tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_2xx, msg);
+ }
+ else if(TSIP_RESPONSE_IS_3456(msg)) {
+ return tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_300_to_699, msg);
+ }
+ else {
+ TSK_DEBUG_WARN("Not supported status code: %d", TSIP_RESPONSE_CODE(msg));
+ return 0;
+ }
+ }
+ // any other response have to be delivered if dst_type is 'network'
+ if(TSIP_TRANSAC(self)->dst->type == tsip_transac_dst_type_net) {
+ return tsip_transac_deliver(TSIP_TRANSAC(self), tsip_transac_incoming_msg, msg);
+ }
+ }
+ break;
+ }
+
+ case tsip_transac_canceled:
+ case tsip_transac_terminated:
+ case tsip_transac_timedout:
+ break;
+
+ case tsip_transac_error: {
+ return tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_error, msg);
+ }
+
+ case tsip_transac_transport_error: {
+ return tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_transporterror, msg);
+ }
+
+ default:
+ break;
+ }
+
+ return 0;
}
int tsip_transac_ict_timer_callback(const tsip_transac_ict_t* self, tsk_timer_id_t timer_id)
{
- int ret = -1;
-
- if(self && TSIP_TRANSAC(self))
- {
- if(timer_id == self->timerA.id){
- ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_timerA, tsk_null);
- }
- else if(timer_id == self->timerB.id){
- ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_timerB, tsk_null);
- }
- else if(timer_id == self->timerD.id){
- ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_timerD, tsk_null);
- }
- else if(timer_id == self->timerM.id){
- ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_timerM, tsk_null);
- }
- }
-
- return ret;
+ int ret = -1;
+
+ if(self && TSIP_TRANSAC(self)) {
+ if(timer_id == self->timerA.id) {
+ ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_timerA, tsk_null);
+ }
+ else if(timer_id == self->timerB.id) {
+ ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_timerB, tsk_null);
+ }
+ else if(timer_id == self->timerD.id) {
+ ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_timerD, tsk_null);
+ }
+ else if(timer_id == self->timerM.id) {
+ ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_timerM, tsk_null);
+ }
+ }
+
+ return ret;
}
@@ -239,135 +233,135 @@ int tsip_transac_ict_timer_callback(const tsip_transac_ict_t* self, tsk_timer_id
**/
int tsip_transac_ict_init(tsip_transac_ict_t *self)
{
- /* Initialize the state machine. */
- tsk_fsm_set(TSIP_TRANSAC_GET_FSM(self),
-
- /*=======================
- * === 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 -> (2xx) -> Accepted
- TSK_FSM_ADD_ALWAYS(_fsm_state_Accepted, _fsm_action_2xx, _fsm_state_Accepted, tsip_transac_ict_Accepted_2_Accepted_X_2xx, "tsip_transac_ict_Accepted_2_Accepted_X_2xx"),
- // 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"),
- // Any -> (cancel) -> Terminated
- TSK_FSM_ADD_ALWAYS(tsk_fsm_state_any, _fsm_action_cancel, _fsm_state_Terminated, tsip_transac_ict_Any_2_Terminated_X_cancel, "tsip_transac_ict_Any_2_Terminated_X_cancel"),
-
- 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_F(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->timerM.timeout = TSIP_TIMER_GET(M);
-
- return 0;
+ /* Initialize the state machine. */
+ tsk_fsm_set(TSIP_TRANSAC_GET_FSM(self),
+
+ /*=======================
+ * === 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 -> (2xx) -> Accepted
+ TSK_FSM_ADD_ALWAYS(_fsm_state_Accepted, _fsm_action_2xx, _fsm_state_Accepted, tsip_transac_ict_Accepted_2_Accepted_X_2xx, "tsip_transac_ict_Accepted_2_Accepted_X_2xx"),
+ // 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"),
+ // Any -> (cancel) -> Terminated
+ TSK_FSM_ADD_ALWAYS(tsk_fsm_state_any, _fsm_action_cancel, _fsm_state_Terminated, tsip_transac_ict_Any_2_Terminated_X_cancel, "tsip_transac_ict_Any_2_Terminated_X_cancel"),
+
+ 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_F(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->timerM.timeout = TSIP_TIMER_GET(M);
+
+ return 0;
}
tsip_transac_ict_t* tsip_transac_ict_create(int32_t cseq_value, const char* callid, tsip_transac_dst_t* dst)
{
- tsip_transac_ict_t* transac = tsk_object_new(tsip_transac_ict_def_t);
- if(transac){
- // initialize base class
- tsip_transac_init(TSIP_TRANSAC(transac), tsip_transac_type_ict, cseq_value, "INVITE", callid, dst, _fsm_state_Started, _fsm_state_Terminated);
-
- // init FSM
- TSIP_TRANSAC_GET_FSM(transac)->debug = DEBUG_STATE_MACHINE;
- tsk_fsm_set_callback_terminated(TSIP_TRANSAC_GET_FSM(transac), TSK_FSM_ONTERMINATED_F(tsip_transac_ict_OnTerminated), (const void*)transac);
-
- // initialize ICT object
- tsip_transac_ict_init(transac);
- }
- return transac;
+ tsip_transac_ict_t* transac = tsk_object_new(tsip_transac_ict_def_t);
+ if(transac) {
+ // initialize base class
+ tsip_transac_init(TSIP_TRANSAC(transac), tsip_transac_type_ict, cseq_value, "INVITE", callid, dst, _fsm_state_Started, _fsm_state_Terminated);
+
+ // init FSM
+ TSIP_TRANSAC_GET_FSM(transac)->debug = DEBUG_STATE_MACHINE;
+ tsk_fsm_set_callback_terminated(TSIP_TRANSAC_GET_FSM(transac), TSK_FSM_ONTERMINATED_F(tsip_transac_ict_OnTerminated), (const void*)transac);
+
+ // initialize ICT object
+ tsip_transac_ict_init(transac);
+ }
+ return transac;
}
/**
* Starts the client transaction.
*
- * @param [in,out] self The client transaction to start.
- * @param [in,out] request The SIP/IMS INVITE request to send.
+ * @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.
+ * @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
- * - Transac will use request branch if exit (e.g. when request received over websocket)
- */
- if((request->firstVia && !tsk_strnullORempty(request->firstVia->branch))){
- tsk_strupdate(&TSIP_TRANSAC(self)->branch, (request->firstVia ? request->firstVia->branch : "doubango"));
- }
- else if((TSIP_TRANSAC(self)->branch = tsk_strdup(TSIP_TRANSAC_MAGIC_COOKIE))){
- tsk_istr_t branch;
- tsk_strrandom(&branch);
- tsk_strcat_2(&(TSIP_TRANSAC(self)->branch), "-%s", branch);
- }
-
- TSIP_TRANSAC(self)->running = 1;
- self->request = tsk_object_ref((void*)request);
-
- ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_send, tsk_null);
- }
- return ret;
+ int ret = -1;
+ if(self && request && !TSIP_TRANSAC(self)->running) {
+ /* Add branch to the new client transaction
+ * - Transac will use request branch if exit (e.g. when request received over websocket)
+ */
+ if((request->firstVia && !tsk_strnullORempty(request->firstVia->branch))) {
+ tsk_strupdate(&TSIP_TRANSAC(self)->branch, (request->firstVia ? request->firstVia->branch : "doubango"));
+ }
+ else if((TSIP_TRANSAC(self)->branch = tsk_strdup(TSIP_TRANSAC_MAGIC_COOKIE))) {
+ tsk_istr_t branch;
+ tsk_strrandom(&branch);
+ tsk_strcat_2(&(TSIP_TRANSAC(self)->branch), "-%s", branch);
+ }
+
+ TSIP_TRANSAC(self)->running = 1;
+ self->request = tsk_object_ref((void*)request);
+
+ ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_send, tsk_null);
+ }
+ return ret;
}
@@ -382,367 +376,367 @@ int tsip_transac_ict_start(tsip_transac_ict_t *self, const tsip_request_t* reque
*/
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));
-
- // Now that the first request is sent using the best transport mean we know if it's reliable or not
- if(TNET_SOCKET_TYPE_IS_VALID(self->request->dst_net_type)){
- TSIP_TRANSAC(self)->reliable = TNET_SOCKET_TYPE_IS_STREAM(self->request->dst_net_type);
- self->timerD.timeout = TSIP_TRANSAC(self)->reliable ? 0 : TSIP_TIMER_GET(D);
- }
-
- /* 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;
+ 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));
+
+ // Now that the first request is sent using the best transport mean we know if it's reliable or not
+ if(TNET_SOCKET_TYPE_IS_VALID(self->request->dst_net_type)) {
+ TSIP_TRANSAC(self)->reliable = TNET_SOCKET_TYPE_IS_STREAM(self->request->dst_net_type);
+ self->timerD.timeout = TSIP_TRANSAC(self)->reliable ? 0 : TSIP_TIMER_GET(D);
+ }
+
+ /* 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 *);
+ 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
+ /* 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.
+ 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.
- */
+ 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);
+ //== 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);
+ self->timerA.timeout *= 2; /* Will not raise indefinitely ==> see timer B */
+ TRANSAC_ICT_TIMER_SCHEDULE(A);
- return 0;
+ 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_deliver(TSIP_TRANSAC(self), tsip_dialog_timedout, tsk_null);
-
- return 0;
+ 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_deliver(TSIP_TRANSAC(self), tsip_dialog_timedout, tsk_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;
-
- /* draft-sparks-sip-invfix-03 - 8.4. Pages 126 through 128
- 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. */
-
- /* draft-sparks-sip-invfix-03 - 8.4. Pages 126 through 128
- The client transaction MUST start timer D when it enters the
- "Completed" state for any reason, 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.
- */
- TRANSAC_ICT_TIMER_SCHEDULE(D); /* timerD already have the right value (0 if reliable and non-zero otherwise) */
-
- /* Send ACK */
- if((ret = tsip_transac_ict_send_ACK(self, response))){
- return ret;
- }
-
- /* Pass the response to the dialog. */
- return tsip_transac_deliver(TSIP_TRANSAC(self), tsip_dialog_i_msg, response);
+ 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;
+
+ /* draft-sparks-sip-invfix-03 - 8.4. Pages 126 through 128
+ 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. */
+
+ /* draft-sparks-sip-invfix-03 - 8.4. Pages 126 through 128
+ The client transaction MUST start timer D when it enters the
+ "Completed" state for any reason, 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.
+ */
+ TRANSAC_ICT_TIMER_SCHEDULE(D); /* timerD already have the right value (0 if reliable and non-zero otherwise) */
+
+ /* Send ACK */
+ if((ret = tsip_transac_ict_send_ACK(self, response))) {
+ return ret;
+ }
+
+ /* Pass the response to the dialog. */
+ return tsip_transac_deliver(TSIP_TRANSAC(self), tsip_dialog_i_msg, response);
}
/* 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_deliver(TSIP_TRANSAC(self), tsip_dialog_i_msg, response);
-
- return 0;
+ 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_deliver(TSIP_TRANSAC(self), tsip_dialog_i_msg, response);
+
+ return 0;
}
/* Calling -> (2xx) -> Accepted
*/
int tsip_transac_ict_Calling_2_Accepted_X_2xx(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 *);
-
- /* draft-sparks-sip-invfix-03 - 8.4. Pages 126 through 128
- When a 2xx response is received while in either the "Calling" or
- "Proceeding" states, the client transaction MUST transition to the
- "Accepted" state, and Timer M MUST be started with a value of
- 64*T1. The 2xx response MUST be passed up to the TU. The client
- transaction MUST NOT generate an ACK to the 2xx response - its
- handling is delegated to the TU.
- */
-
- /* Schedule timer M */
- TRANSAC_ICT_TIMER_SCHEDULE(M);
-
- /* Cancel timers A and B */
- if(!TSIP_TRANSAC(self)->reliable){
- TRANSAC_ICT_TIMER_SCHEDULE(A);
- }
- TRANSAC_ICT_TIMER_SCHEDULE(B);
-
- /* pass the response to the TU (dialog) */
- return tsip_transac_deliver(TSIP_TRANSAC(self), tsip_dialog_i_msg, response);
+ tsip_transac_ict_t *self = va_arg(*app, tsip_transac_ict_t *);
+ const tsip_response_t *response = va_arg(*app, const tsip_response_t *);
+
+ /* draft-sparks-sip-invfix-03 - 8.4. Pages 126 through 128
+ When a 2xx response is received while in either the "Calling" or
+ "Proceeding" states, the client transaction MUST transition to the
+ "Accepted" state, and Timer M MUST be started with a value of
+ 64*T1. The 2xx response MUST be passed up to the TU. The client
+ transaction MUST NOT generate an ACK to the 2xx response - its
+ handling is delegated to the TU.
+ */
+
+ /* Schedule timer M */
+ TRANSAC_ICT_TIMER_SCHEDULE(M);
+
+ /* Cancel timers A and B */
+ if(!TSIP_TRANSAC(self)->reliable) {
+ TRANSAC_ICT_TIMER_SCHEDULE(A);
+ }
+ TRANSAC_ICT_TIMER_SCHEDULE(B);
+
+ /* pass the response to the TU (dialog) */
+ return tsip_transac_deliver(TSIP_TRANSAC(self), tsip_dialog_i_msg, response);
}
/* Proceeding -> (1xx) -> Proceeding
*/
int tsip_transac_ict_Proceeding_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 *);
+ tsip_transac_ict_t *self = va_arg(*app, tsip_transac_ict_t *);
+ const tsip_response_t *response = va_arg(*app, const tsip_response_t *);
- /* pass the response to the TU (dialog) */
- return tsip_transac_deliver(TSIP_TRANSAC(self), tsip_dialog_i_msg, response);
+ /* pass the response to the TU (dialog) */
+ return tsip_transac_deliver(TSIP_TRANSAC(self), tsip_dialog_i_msg, response);
}
/* 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;
-
- /* draft-sparks-sip-invfix-03 - 8.4. Pages 126 through 128
- 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. */
-
- /* draft-sparks-sip-invfix-03 - 8.4. Pages 126 through 128
- The client transaction MUST start timer D when it enters the
- "Completed" state for any reason, 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.
- */
- TRANSAC_ICT_TIMER_SCHEDULE(D); /* timerD already have the right value (0 if reliable and non-zero otherwise) */
-
- /* Send ACK */
- if((ret = tsip_transac_ict_send_ACK(self, response))){
- return ret;
- }
-
- /* Pass the response to the dialog. */
- ret = tsip_transac_deliver(TSIP_TRANSAC(self), tsip_dialog_i_msg, response);
-
- return ret;
+ 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;
+
+ /* draft-sparks-sip-invfix-03 - 8.4. Pages 126 through 128
+ 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. */
+
+ /* draft-sparks-sip-invfix-03 - 8.4. Pages 126 through 128
+ The client transaction MUST start timer D when it enters the
+ "Completed" state for any reason, 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.
+ */
+ TRANSAC_ICT_TIMER_SCHEDULE(D); /* timerD already have the right value (0 if reliable and non-zero otherwise) */
+
+ /* Send ACK */
+ if((ret = tsip_transac_ict_send_ACK(self, response))) {
+ return ret;
+ }
+
+ /* Pass the response to the dialog. */
+ ret = tsip_transac_deliver(TSIP_TRANSAC(self), tsip_dialog_i_msg, response);
+
+ return ret;
}
/* Proceeding -> (2xx) -> Accepted
*/
int tsip_transac_ict_Proceeding_2_Accepted_X_2xx(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 *);
-
- /* draft-sparks-sip-invfix-03 - 8.4. Pages 126 through 128
- When a 2xx response is received while in either the "Calling" or
- "Proceeding" states, the client transaction MUST transition to the
- "Accepted" state, and Timer M MUST be started with a value of
- 64*T1. The 2xx response MUST be passed up to the TU. The client
- transaction MUST NOT generate an ACK to the 2xx response - its
- handling is delegated to the TU.
- */
-
- /* Schedule timer M */
- TRANSAC_ICT_TIMER_SCHEDULE(M);
-
- /* Cancel timers A and B */
- if(!TSIP_TRANSAC(self)->reliable){
- TRANSAC_ICT_TIMER_SCHEDULE(A);
- }
- TRANSAC_ICT_TIMER_SCHEDULE(B);
-
- /* pass the response to the TU (dialog) */
- return tsip_transac_deliver(TSIP_TRANSAC(self), tsip_dialog_i_msg, response);
+ tsip_transac_ict_t *self = va_arg(*app, tsip_transac_ict_t *);
+ const tsip_response_t *response = va_arg(*app, const tsip_response_t *);
+
+ /* draft-sparks-sip-invfix-03 - 8.4. Pages 126 through 128
+ When a 2xx response is received while in either the "Calling" or
+ "Proceeding" states, the client transaction MUST transition to the
+ "Accepted" state, and Timer M MUST be started with a value of
+ 64*T1. The 2xx response MUST be passed up to the TU. The client
+ transaction MUST NOT generate an ACK to the 2xx response - its
+ handling is delegated to the TU.
+ */
+
+ /* Schedule timer M */
+ TRANSAC_ICT_TIMER_SCHEDULE(M);
+
+ /* Cancel timers A and B */
+ if(!TSIP_TRANSAC(self)->reliable) {
+ TRANSAC_ICT_TIMER_SCHEDULE(A);
+ }
+ TRANSAC_ICT_TIMER_SCHEDULE(B);
+
+ /* pass the response to the TU (dialog) */
+ return tsip_transac_deliver(TSIP_TRANSAC(self), tsip_dialog_i_msg, response);
}
/* 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 *);
-
- /* draft-sparks-sip-invfix-03 - 8.4. Pages 126 through 128
- Any retransmissions of a response with status code 300-699 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.
- */
-
- return tsip_transac_ict_send_ACK(self, response);
+ tsip_transac_ict_t *self = va_arg(*app, tsip_transac_ict_t *);
+ const tsip_response_t *response = va_arg(*app, const tsip_response_t *);
+
+ /* draft-sparks-sip-invfix-03 - 8.4. Pages 126 through 128
+ Any retransmissions of a response with status code 300-699 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.
+ */
+
+ return tsip_transac_ict_send_ACK(self, response);
}
/* Completed -> (timerD) -> Terminated
*/
int tsip_transac_ict_Completed_2_Terminated_X_timerD(va_list *app)
{
- /* draft-sparks-sip-invfix-03 - 8.4. Pages 126 through 128
- 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;
+ /* draft-sparks-sip-invfix-03 - 8.4. Pages 126 through 128
+ 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 -> (2xx) -> Accepted
*/
int tsip_transac_ict_Accepted_2_Accepted_X_2xx(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 *);
-
- /* draft-sparks-sip-invfix-03 - 7.2. UAC Impacts
- A 2xx response received while in the "Accepted" state MUST be passed to the TU and
- the machine remains in the "Accepted" state. The client transaction
- MUST NOT generate an ACK to any 2xx response on its own. The TU
- responsible for the transaction will generate the ACK.
- */
-
- /* Pass the response to the TU. */
- tsip_transac_deliver(TSIP_TRANSAC(self), tsip_dialog_i_msg, response);
-
- return 0;
+ tsip_transac_ict_t *self = va_arg(*app, tsip_transac_ict_t *);
+ const tsip_response_t *response = va_arg(*app, const tsip_response_t *);
+
+ /* draft-sparks-sip-invfix-03 - 7.2. UAC Impacts
+ A 2xx response received while in the "Accepted" state MUST be passed to the TU and
+ the machine remains in the "Accepted" state. The client transaction
+ MUST NOT generate an ACK to any 2xx response on its own. The TU
+ responsible for the transaction will generate the ACK.
+ */
+
+ /* Pass the response to the TU. */
+ tsip_transac_deliver(TSIP_TRANSAC(self), tsip_dialog_i_msg, response);
+
+ return 0;
}
/* Accepted -> (timerM) -> Terminated
*/
int tsip_transac_ict_Accepted_2_Terminated_X_timerM(va_list *app)
{
- /* draft-sparks-sip-invfix-03 - 8.4. Pages 126 through 128
- If timer M fires while the client transaction is in the "Accepted"
- state, the client transaction MUST move to the "Terminated" state.
- */
- return 0;
+ /* draft-sparks-sip-invfix-03 - 8.4. Pages 126 through 128
+ If timer M fires while the client transaction is in the "Accepted"
+ state, the client transaction MUST move to the "Terminated" state.
+ */
+ return 0;
}
/* Any -> (Transport Error) -> Terminated
*/
int tsip_transac_ict_Any_2_Terminated_X_transportError(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 *);
+ tsip_transac_ict_t *self = va_arg(*app, tsip_transac_ict_t *);
+ //const tsip_message_t *message = va_arg(*app, const tsip_message_t *);
- /* Timers will be canceled by "tsip_transac_ict_OnTerminated" */
+ /* Timers will be canceled by "tsip_transac_ict_OnTerminated" */
- return tsip_transac_deliver(TSIP_TRANSAC(self), tsip_dialog_transport_error, tsk_null);
+ return tsip_transac_deliver(TSIP_TRANSAC(self), tsip_dialog_transport_error, tsk_null);
}
/* Any -> (Error) -> Terminated
*/
int tsip_transac_ict_Any_2_Terminated_X_Error(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 *);
+ tsip_transac_ict_t *self = va_arg(*app, tsip_transac_ict_t *);
+ //const tsip_message_t *message = va_arg(*app, const tsip_message_t *);
- /* Timers will be canceled by "tsip_transac_ict_OnTerminated" */
+ /* Timers will be canceled by "tsip_transac_ict_OnTerminated" */
- return tsip_transac_deliver(TSIP_TRANSAC(self), tsip_dialog_error, tsk_null);
+ return tsip_transac_deliver(TSIP_TRANSAC(self), tsip_dialog_error, tsk_null);
}
/* Any -> (cancel) -> Terminated
*/
int tsip_transac_ict_Any_2_Terminated_X_cancel(va_list *app)
{
- /* doubango-specific */
- return 0;
+ /* doubango-specific */
+ return 0;
}
@@ -754,102 +748,101 @@ int tsip_transac_ict_Any_2_Terminated_X_cancel(va_list *app)
*/
int tsip_transac_ict_send_ACK(tsip_transac_ict_t *self, const tsip_response_t* response)
{
- int ret = -1;
- tsip_request_t *request = tsk_null;
- const tsk_list_item_t* item;
-
- if(!self || !self->request || !response){
- goto bail;
- }
-
- // check lastINVITE
- if( !self->request->firstVia ||
- !self->request->From ||
- !self->request->line.request.uri ||
- !self->request->Call_ID ||
- !self->request->CSeq)
- {
- ret = -2;
- goto bail;
- }
-
- // check response
- if(!response->To){
- ret = -3;
- goto bail;
- }
-
- /* RFC 3261 - 17.1.1.3 Construction of the ACK Request
-
- The ACK request constructed by the client transaction MUST contain
- values for the Call-ID, From, and Request-URI that are equal to the
- values of those header fields in the request passed to the transport
- by the client transaction (call this the "original request"). The To
- header field in the ACK MUST equal the To header field in the
- response being acknowledged, and therefore will usually differ from
- the To header field in the original request by the addition of the
- tag parameter. The ACK MUST contain a single Via header field, and
- this MUST be equal to the top Via header field of the original
- request. The CSeq header field in the ACK MUST contain the same
- value for the sequence number as was present in the original request,
- but the method parameter MUST be equal to "ACK".
-
- If the INVITE request whose response is being acknowledged had Route
- header fields, those header fields MUST appear in the ACK. This is
- to ensure that the ACK can be routed properly through any downstream
- stateless proxies.
-
- Although any request MAY contain a body, a body in an ACK is special
- since the request cannot be rejected if the body is not understood.
- Therefore, placement of bodies in ACK for non-2xx is NOT RECOMMENDED,
- but if done, the body types are restricted to any that appeared in
- the INVITE, assuming that the response to the INVITE was not 415. If
- it was, the body in the ACK MAY be any type listed in the Accept
- header field in the 415.
- */
- if((request = tsip_request_new("ACK", self->request->line.request.uri, self->request->From->uri, response->To->uri, self->request->Call_ID->value, self->request->CSeq->seq))){
- // Via
- request->firstVia = tsk_object_ref((void*)self->request->firstVia);
- // tags
- if(request->From){
- request->From->tag = tsk_strdup(self->request->From->tag);
- }
- if(request->To){
- request->To->tag = tsk_strdup(response->To->tag);
- }
- // Routes
- tsk_list_foreach(item, self->request->headers){
- const tsip_header_t* curr = item->data;
- if(curr->type == tsip_htype_Route){
- tsip_message_add_header(request, curr);
- }
- }
-
- // SigComp
- if(TSIP_TRANSAC_GET_SESSION(self) && TSIP_TRANSAC_GET_SESSION(self)->sigcomp_id){
- request->sigcomp_id = tsk_strdup(TSIP_TRANSAC_GET_SESSION(self)->sigcomp_id);
- }
-
- // send the request
- ret = tsip_transac_send(TSIP_TRANSAC(self), request->firstVia->branch, request);
- TSK_OBJECT_SAFE_FREE(request);
- }
+ int ret = -1;
+ tsip_request_t *request = tsk_null;
+ const tsk_list_item_t* item;
+
+ if(!self || !self->request || !response) {
+ goto bail;
+ }
+
+ // check lastINVITE
+ if( !self->request->firstVia ||
+ !self->request->From ||
+ !self->request->line.request.uri ||
+ !self->request->Call_ID ||
+ !self->request->CSeq) {
+ ret = -2;
+ goto bail;
+ }
+
+ // check response
+ if(!response->To) {
+ ret = -3;
+ goto bail;
+ }
+
+ /* RFC 3261 - 17.1.1.3 Construction of the ACK Request
+
+ The ACK request constructed by the client transaction MUST contain
+ values for the Call-ID, From, and Request-URI that are equal to the
+ values of those header fields in the request passed to the transport
+ by the client transaction (call this the "original request"). The To
+ header field in the ACK MUST equal the To header field in the
+ response being acknowledged, and therefore will usually differ from
+ the To header field in the original request by the addition of the
+ tag parameter. The ACK MUST contain a single Via header field, and
+ this MUST be equal to the top Via header field of the original
+ request. The CSeq header field in the ACK MUST contain the same
+ value for the sequence number as was present in the original request,
+ but the method parameter MUST be equal to "ACK".
+
+ If the INVITE request whose response is being acknowledged had Route
+ header fields, those header fields MUST appear in the ACK. This is
+ to ensure that the ACK can be routed properly through any downstream
+ stateless proxies.
+
+ Although any request MAY contain a body, a body in an ACK is special
+ since the request cannot be rejected if the body is not understood.
+ Therefore, placement of bodies in ACK for non-2xx is NOT RECOMMENDED,
+ but if done, the body types are restricted to any that appeared in
+ the INVITE, assuming that the response to the INVITE was not 415. If
+ it was, the body in the ACK MAY be any type listed in the Accept
+ header field in the 415.
+ */
+ if((request = tsip_request_new("ACK", self->request->line.request.uri, self->request->From->uri, response->To->uri, self->request->Call_ID->value, self->request->CSeq->seq))) {
+ // Via
+ request->firstVia = tsk_object_ref((void*)self->request->firstVia);
+ // tags
+ if(request->From) {
+ request->From->tag = tsk_strdup(self->request->From->tag);
+ }
+ if(request->To) {
+ request->To->tag = tsk_strdup(response->To->tag);
+ }
+ // Routes
+ tsk_list_foreach(item, self->request->headers) {
+ const tsip_header_t* curr = item->data;
+ if(curr->type == tsip_htype_Route) {
+ tsip_message_add_header(request, curr);
+ }
+ }
+
+ // SigComp
+ if(TSIP_TRANSAC_GET_SESSION(self) && TSIP_TRANSAC_GET_SESSION(self)->sigcomp_id) {
+ request->sigcomp_id = tsk_strdup(TSIP_TRANSAC_GET_SESSION(self)->sigcomp_id);
+ }
+
+ // send the request
+ ret = tsip_transac_send(TSIP_TRANSAC(self), request->firstVia->branch, request);
+ TSK_OBJECT_SAFE_FREE(request);
+ }
bail:
- return ret;
+ return ret;
}
/*== TERMINATED
*/
int tsip_transac_ict_OnTerminated(tsip_transac_ict_t *self)
{
- /* draft-sparks-sip-invfix-03 - 8.4. Pages 126 through 128
- The client transaction MUST be destroyed the instant it enters the "Terminated" state.
- */
- TSK_DEBUG_INFO("=== ICT terminated ===");
-
- /* Remove (and destroy) the transaction from the layer. */
- return tsip_transac_remove(TSIP_TRANSAC(self));
+ /* draft-sparks-sip-invfix-03 - 8.4. Pages 126 through 128
+ The client transaction MUST be destroyed the instant it enters the "Terminated" state.
+ */
+ TSK_DEBUG_INFO("=== ICT terminated ===");
+
+ /* Remove (and destroy) the transaction from the layer. */
+ return tsip_transac_remove(TSIP_TRANSAC(self));
}
@@ -883,45 +876,44 @@ int tsip_transac_ict_OnTerminated(tsip_transac_ict_t *self)
//
static tsk_object_t* tsip_transac_ict_ctor(tsk_object_t * self, va_list * app)
{
- tsip_transac_ict_t *transac = self;
- if(transac){
- }
- return self;
+ tsip_transac_ict_t *transac = self;
+ if(transac) {
+ }
+ return self;
}
static tsk_object_t* tsip_transac_ict_dtor(tsk_object_t * _self)
-{
- tsip_transac_ict_t *self = _self;
- if(self){
- /* 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 = tsk_false;
- TSK_OBJECT_SAFE_FREE(self->request);
-
- /* DeInitialize base class */
- tsip_transac_deinit(TSIP_TRANSAC(self));
-
- TSK_DEBUG_INFO("*** ICT destroyed ***");
- }
- return _self;
+{
+ tsip_transac_ict_t *self = _self;
+ if(self) {
+ /* 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 = tsk_false;
+ TSK_OBJECT_SAFE_FREE(self->request);
+
+ /* DeInitialize base class */
+ tsip_transac_deinit(TSIP_TRANSAC(self));
+
+ TSK_DEBUG_INFO("*** ICT destroyed ***");
+ }
+ return _self;
}
static int tsip_transac_ict_cmp(const tsk_object_t *t1, const tsk_object_t *t2)
{
- return tsip_transac_cmp(t1, 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_ctor,
- tsip_transac_ict_dtor,
- tsip_transac_ict_cmp,
+static const tsk_object_def_t tsip_transac_ict_def_s = {
+ sizeof(tsip_transac_ict_t),
+ tsip_transac_ict_ctor,
+ tsip_transac_ict_dtor,
+ tsip_transac_ict_cmp,
};
const tsk_object_def_t *tsip_transac_ict_def_t = &tsip_transac_ict_def_s;
diff --git a/tinySIP/src/transactions/tsip_transac_ist.c b/tinySIP/src/transactions/tsip_transac_ist.c
index f4f9233..fc03388 100755
--- a/tinySIP/src/transactions/tsip_transac_ist.c
+++ b/tinySIP/src/transactions/tsip_transac_ist.c
@@ -2,19 +2,19 @@
* Copyright (C) 2010-2011 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -120,241 +120,233 @@ static int tsip_transac_ist_Any_2_Terminated_X_cancel(va_list *app); /* doubango
/* ======================== conds ======================== */
static tsk_bool_t _fsm_cond_is_resp2INVITE(tsip_transac_ist_t* self, tsip_message_t* message)
{
- return TSIP_RESPONSE_IS_TO_INVITE(message);
+ return TSIP_RESPONSE_IS_TO_INVITE(message);
}
/* ======================== actions ======================== */
-typedef enum _fsm_action_e
-{
- _fsm_action_cancel = tsip_atype_cancel,
-
- _fsm_action_recv_INVITE = 0xFF,
- _fsm_action_recv_ACK,
- _fsm_action_send_1xx,
- _fsm_action_send_2xx,
- _fsm_action_send_300_to_699,
- _fsm_action_send_non1xx,
- _fsm_action_timerH,
- _fsm_action_timerI,
- _fsm_action_timerG,
- _fsm_action_timerL,
- _fsm_action_timerX,
- _fsm_action_transporterror,
- _fsm_action_error,
+typedef enum _fsm_action_e {
+ _fsm_action_cancel = tsip_atype_cancel,
+
+ _fsm_action_recv_INVITE = 0xFF,
+ _fsm_action_recv_ACK,
+ _fsm_action_send_1xx,
+ _fsm_action_send_2xx,
+ _fsm_action_send_300_to_699,
+ _fsm_action_send_non1xx,
+ _fsm_action_timerH,
+ _fsm_action_timerI,
+ _fsm_action_timerG,
+ _fsm_action_timerL,
+ _fsm_action_timerX,
+ _fsm_action_transporterror,
+ _fsm_action_error,
}
_fsm_action_t;
/* ======================== states ======================== */
-typedef enum _fsm_state_e
-{
- _fsm_state_Started,
- _fsm_state_Proceeding,
- _fsm_state_Completed,
- _fsm_state_Accepted,
- _fsm_state_Confirmed,
- _fsm_state_Terminated
+typedef enum _fsm_state_e {
+ _fsm_state_Started,
+ _fsm_state_Proceeding,
+ _fsm_state_Completed,
+ _fsm_state_Accepted,
+ _fsm_state_Confirmed,
+ _fsm_state_Terminated
}
_fsm_state_t;
int tsip_transac_ist_event_callback(const tsip_transac_ist_t *self, tsip_transac_event_type_t type, const tsip_message_t *msg)
{
- int ret = -1;
-
- switch(type)
- {
- case tsip_transac_incoming_msg: /* From Transport Layer to Transaction Layer */
- {
- if(msg && TSIP_MESSAGE_IS_REQUEST(msg)){
- if(TSIP_REQUEST_IS_INVITE(msg)){
- ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_recv_INVITE, msg);
- }
- else if(TSIP_REQUEST_IS_ACK(msg)){
- ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_recv_ACK, msg);
- }
- }
- break;
- }
-
- case tsip_transac_outgoing_msg: /* From TU to Transport Layer */
- {
- if(msg && TSIP_MESSAGE_IS_RESPONSE(msg))
- {
- if(TSIP_RESPONSE_IS_1XX(msg)){
- ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_send_1xx, msg);
- }
- else if(TSIP_RESPONSE_IS_2XX(msg)){
- ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_send_2xx, msg);
- }
- else if(TSIP_RESPONSE_IS_3456(msg)){
- ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_send_300_to_699, msg);
- }
- }
- break;
- }
-
- case tsip_transac_canceled:
- case tsip_transac_terminated:
- case tsip_transac_timedout:
- break;
-
- case tsip_transac_error:
- {
- ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_error, msg);
- break;
- }
-
- case tsip_transac_transport_error:
- {
- ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_transporterror, msg);
- break;
- }
- }
-
- return ret;
+ int ret = -1;
+
+ switch(type) {
+ case tsip_transac_incoming_msg: { /* From Transport Layer to Transaction Layer */
+ if(msg && TSIP_MESSAGE_IS_REQUEST(msg)) {
+ if(TSIP_REQUEST_IS_INVITE(msg)) {
+ ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_recv_INVITE, msg);
+ }
+ else if(TSIP_REQUEST_IS_ACK(msg)) {
+ ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_recv_ACK, msg);
+ }
+ }
+ break;
+ }
+
+ case tsip_transac_outgoing_msg: { /* From TU to Transport Layer */
+ if(msg && TSIP_MESSAGE_IS_RESPONSE(msg)) {
+ if(TSIP_RESPONSE_IS_1XX(msg)) {
+ ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_send_1xx, msg);
+ }
+ else if(TSIP_RESPONSE_IS_2XX(msg)) {
+ ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_send_2xx, msg);
+ }
+ else if(TSIP_RESPONSE_IS_3456(msg)) {
+ ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_send_300_to_699, msg);
+ }
+ }
+ break;
+ }
+
+ case tsip_transac_canceled:
+ case tsip_transac_terminated:
+ case tsip_transac_timedout:
+ break;
+
+ case tsip_transac_error: {
+ ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_error, msg);
+ break;
+ }
+
+ case tsip_transac_transport_error: {
+ ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_transporterror, msg);
+ break;
+ }
+ }
+
+ return ret;
}
int tsip_transac_ist_timer_callback(const tsip_transac_ist_t* self, tsk_timer_id_t timer_id)
{
- int ret = -1;
-
- if(self){
- if(timer_id == self->timerH.id){
- ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_timerH, tsk_null);
- }
- else if(timer_id == self->timerI.id){
- ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_timerI, tsk_null);
- }
- else if(timer_id == self->timerG.id){
- ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_timerG, tsk_null);
- }
- else if(timer_id == self->timerL.id){
- ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_timerL, tsk_null);
- }
- else if(timer_id == self->timerX.id){
- ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_timerX, tsk_null);
- }
- }
-
- return ret;
+ int ret = -1;
+
+ if(self) {
+ if(timer_id == self->timerH.id) {
+ ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_timerH, tsk_null);
+ }
+ else if(timer_id == self->timerI.id) {
+ ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_timerI, tsk_null);
+ }
+ else if(timer_id == self->timerG.id) {
+ ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_timerG, tsk_null);
+ }
+ else if(timer_id == self->timerL.id) {
+ ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_timerL, tsk_null);
+ }
+ else if(timer_id == self->timerX.id) {
+ ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_timerX, tsk_null);
+ }
+ }
+
+ return ret;
}
int tsip_transac_ist_init(tsip_transac_ist_t *self)
{
- /* Initialize the state machine.
- */
- tsk_fsm_set(TSIP_TRANSAC_GET_FSM(self),
-
- /*=======================
- * === Started ===
- */
- // Started -> (recv INVITE) -> Proceeding
- TSK_FSM_ADD_ALWAYS(_fsm_state_Started, _fsm_action_recv_INVITE, _fsm_state_Proceeding, tsip_transac_ist_Started_2_Proceeding_X_INVITE, "tsip_transac_ist_Started_2_Proceeding_X_INVITE"),
- // Started -> (Any other) -> Started
- TSK_FSM_ADD_ALWAYS_NOTHING(_fsm_state_Started, "tsip_transac_ist_Started_2_Started_X_any"),
-
- /*=======================
- * === Proceeding ===
- */
- // Proceeding -> (recv INVITE) -> Proceeding
- TSK_FSM_ADD_ALWAYS(_fsm_state_Proceeding, _fsm_action_recv_INVITE, _fsm_state_Proceeding, tsip_transac_ist_Proceeding_2_Proceeding_X_INVITE, "tsip_transac_ist_Proceeding_2_Proceeding_X_INVITE"),
- // Proceeding -> (send 1xx) -> Proceeding
- TSK_FSM_ADD(_fsm_state_Proceeding, _fsm_action_send_1xx, _fsm_cond_is_resp2INVITE, _fsm_state_Proceeding, tsip_transac_ist_Proceeding_2_Proceeding_X_1xx, "tsip_transac_ist_Proceeding_2_Proceeding_X_1xx"),
- // Proceeding -> (send 300to699) -> Completed
- TSK_FSM_ADD(_fsm_state_Proceeding, _fsm_action_send_300_to_699, _fsm_cond_is_resp2INVITE, _fsm_state_Completed, tsip_transac_ist_Proceeding_2_Completed_X_300_to_699, "tsip_transac_ist_Proceeding_2_Completed_X_300_to_699"),
- // Proceeding -> (send 2xx) -> Accepted
- TSK_FSM_ADD(_fsm_state_Proceeding, _fsm_action_send_2xx, _fsm_cond_is_resp2INVITE, _fsm_state_Accepted, tsip_transac_ist_Proceeding_2_Accepted_X_2xx, "tsip_transac_ist_Proceeding_2_Accepted_X_2xx"),
-
- /*=======================
- * === Completed ===
- */
- // Completed -> (recv INVITE) -> Completed
- TSK_FSM_ADD_ALWAYS(_fsm_state_Completed, _fsm_action_recv_INVITE, _fsm_state_Completed, tsip_transac_ist_Completed_2_Completed_INVITE, "tsip_transac_ist_Completed_2_Completed_INVITE"),
- // Completed -> (timer G) -> Completed
- TSK_FSM_ADD_ALWAYS(_fsm_state_Completed, _fsm_action_timerG, _fsm_state_Completed, tsip_transac_ist_Completed_2_Completed_timerG, "tsip_transac_ist_Completed_2_Completed_timerG"),
- // Completed -> (timerH) -> Terminated
- TSK_FSM_ADD_ALWAYS(_fsm_state_Completed, _fsm_action_timerH, _fsm_state_Terminated, tsip_transac_ist_Completed_2_Terminated_timerH, "tsip_transac_ist_Completed_2_Terminated_timerH"),
- // Completed -> (recv ACK) -> Confirmed
- TSK_FSM_ADD_ALWAYS(_fsm_state_Completed, _fsm_action_recv_ACK, _fsm_state_Confirmed, tsip_transac_ist_Completed_2_Confirmed_ACK, "tsip_transac_ist_Completed_2_Confirmed_ACK"),
-
- /*=======================
- * === Accepted ===
- */
- // Accepted -> (recv INVITE) -> Accepted
- TSK_FSM_ADD_ALWAYS(_fsm_state_Accepted, _fsm_action_recv_INVITE, _fsm_state_Accepted, tsip_transac_ist_Accepted_2_Accepted_INVITE, "tsip_transac_ist_Accepted_2_Accepted_INVITE"),
- // Accepted -> (send 2xx) -> Accepted
- TSK_FSM_ADD(_fsm_state_Accepted, _fsm_action_send_2xx, _fsm_cond_is_resp2INVITE, _fsm_state_Accepted, tsip_transac_ist_Accepted_2_Accepted_2xx, "tsip_transac_ist_Accepted_2_Accepted_2xx"),
- // Accepted -> (timer X) -> Accepted
- TSK_FSM_ADD_ALWAYS(_fsm_state_Accepted, _fsm_action_timerX, _fsm_state_Accepted, tsip_transac_ist_Accepted_2_Accepted_timerX, "tsip_transac_ist_Accepted_2_Accepted_timerX"),
- // Accepted -> (recv ACK) -> Accepted
- TSK_FSM_ADD_ALWAYS(_fsm_state_Accepted, _fsm_action_recv_ACK, _fsm_state_Accepted, tsip_transac_ist_Accepted_2_Accepted_iACK, "tsip_transac_ist_Accepted_2_Accepted_iACK"),
- // Accepted -> (timerL) -> Terminated
- TSK_FSM_ADD_ALWAYS(_fsm_state_Accepted, _fsm_action_timerL, _fsm_state_Terminated, tsip_transac_ist_Accepted_2_Terminated_timerL, "tsip_transac_ist_Accepted_2_Terminated_timerL"),
-
- /*=======================
- * === Confirmed ===
- */
- // Confirmed -> (timerI) -> Terminated
- TSK_FSM_ADD_ALWAYS(_fsm_state_Confirmed, _fsm_action_timerI, _fsm_state_Terminated, tsip_transac_ist_Confirmed_2_Terminated_timerI, "tsip_transac_ist_Confirmed_2_Terminated_timerI"),
-
-
- /*=======================
- * === Any ===
- */
- // Any -> (transport error) -> Terminated
- TSK_FSM_ADD_ALWAYS(tsk_fsm_state_any, _fsm_action_transporterror, _fsm_state_Terminated, tsip_transac_ist_Any_2_Terminated_X_transportError, "tsip_transac_ist_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_ist_Any_2_Terminated_X_Error, "tsip_transac_ist_Any_2_Terminated_X_Error"),
- // Any -> (cancel) -> Terminated
- TSK_FSM_ADD_ALWAYS(tsk_fsm_state_any, _fsm_action_cancel, _fsm_state_Terminated, tsip_transac_ist_Any_2_Terminated_X_cancel, "tsip_transac_ist_Any_2_Terminated_X_cancel"),
-
-
- TSK_FSM_ADD_NULL());
-
- /* Set callback function to call when new messages arrive or errors happen at
- the transport layer.
- */
- TSIP_TRANSAC(self)->callback = TSIP_TRANSAC_EVENT_CALLBACK_F(tsip_transac_ist_event_callback);
-
- /* Set Timers
- * RFC 3261 17.2.1: For unreliable transports, timer G is set to fire in T1 seconds, and is not set to fire for
- reliable transports.
- */
- self->timerH.timeout = TSIP_TIMER_GET(H);
- self->timerG.timeout = TSIP_TIMER_GET(G);
- self->timerL.timeout = TSIP_TIMER_GET(L);
- self->timerX.timeout = TSIP_TIMER_GET(G);
-
- return 0;
+ /* Initialize the state machine.
+ */
+ tsk_fsm_set(TSIP_TRANSAC_GET_FSM(self),
+
+ /*=======================
+ * === Started ===
+ */
+ // Started -> (recv INVITE) -> Proceeding
+ TSK_FSM_ADD_ALWAYS(_fsm_state_Started, _fsm_action_recv_INVITE, _fsm_state_Proceeding, tsip_transac_ist_Started_2_Proceeding_X_INVITE, "tsip_transac_ist_Started_2_Proceeding_X_INVITE"),
+ // Started -> (Any other) -> Started
+ TSK_FSM_ADD_ALWAYS_NOTHING(_fsm_state_Started, "tsip_transac_ist_Started_2_Started_X_any"),
+
+ /*=======================
+ * === Proceeding ===
+ */
+ // Proceeding -> (recv INVITE) -> Proceeding
+ TSK_FSM_ADD_ALWAYS(_fsm_state_Proceeding, _fsm_action_recv_INVITE, _fsm_state_Proceeding, tsip_transac_ist_Proceeding_2_Proceeding_X_INVITE, "tsip_transac_ist_Proceeding_2_Proceeding_X_INVITE"),
+ // Proceeding -> (send 1xx) -> Proceeding
+ TSK_FSM_ADD(_fsm_state_Proceeding, _fsm_action_send_1xx, _fsm_cond_is_resp2INVITE, _fsm_state_Proceeding, tsip_transac_ist_Proceeding_2_Proceeding_X_1xx, "tsip_transac_ist_Proceeding_2_Proceeding_X_1xx"),
+ // Proceeding -> (send 300to699) -> Completed
+ TSK_FSM_ADD(_fsm_state_Proceeding, _fsm_action_send_300_to_699, _fsm_cond_is_resp2INVITE, _fsm_state_Completed, tsip_transac_ist_Proceeding_2_Completed_X_300_to_699, "tsip_transac_ist_Proceeding_2_Completed_X_300_to_699"),
+ // Proceeding -> (send 2xx) -> Accepted
+ TSK_FSM_ADD(_fsm_state_Proceeding, _fsm_action_send_2xx, _fsm_cond_is_resp2INVITE, _fsm_state_Accepted, tsip_transac_ist_Proceeding_2_Accepted_X_2xx, "tsip_transac_ist_Proceeding_2_Accepted_X_2xx"),
+
+ /*=======================
+ * === Completed ===
+ */
+ // Completed -> (recv INVITE) -> Completed
+ TSK_FSM_ADD_ALWAYS(_fsm_state_Completed, _fsm_action_recv_INVITE, _fsm_state_Completed, tsip_transac_ist_Completed_2_Completed_INVITE, "tsip_transac_ist_Completed_2_Completed_INVITE"),
+ // Completed -> (timer G) -> Completed
+ TSK_FSM_ADD_ALWAYS(_fsm_state_Completed, _fsm_action_timerG, _fsm_state_Completed, tsip_transac_ist_Completed_2_Completed_timerG, "tsip_transac_ist_Completed_2_Completed_timerG"),
+ // Completed -> (timerH) -> Terminated
+ TSK_FSM_ADD_ALWAYS(_fsm_state_Completed, _fsm_action_timerH, _fsm_state_Terminated, tsip_transac_ist_Completed_2_Terminated_timerH, "tsip_transac_ist_Completed_2_Terminated_timerH"),
+ // Completed -> (recv ACK) -> Confirmed
+ TSK_FSM_ADD_ALWAYS(_fsm_state_Completed, _fsm_action_recv_ACK, _fsm_state_Confirmed, tsip_transac_ist_Completed_2_Confirmed_ACK, "tsip_transac_ist_Completed_2_Confirmed_ACK"),
+
+ /*=======================
+ * === Accepted ===
+ */
+ // Accepted -> (recv INVITE) -> Accepted
+ TSK_FSM_ADD_ALWAYS(_fsm_state_Accepted, _fsm_action_recv_INVITE, _fsm_state_Accepted, tsip_transac_ist_Accepted_2_Accepted_INVITE, "tsip_transac_ist_Accepted_2_Accepted_INVITE"),
+ // Accepted -> (send 2xx) -> Accepted
+ TSK_FSM_ADD(_fsm_state_Accepted, _fsm_action_send_2xx, _fsm_cond_is_resp2INVITE, _fsm_state_Accepted, tsip_transac_ist_Accepted_2_Accepted_2xx, "tsip_transac_ist_Accepted_2_Accepted_2xx"),
+ // Accepted -> (timer X) -> Accepted
+ TSK_FSM_ADD_ALWAYS(_fsm_state_Accepted, _fsm_action_timerX, _fsm_state_Accepted, tsip_transac_ist_Accepted_2_Accepted_timerX, "tsip_transac_ist_Accepted_2_Accepted_timerX"),
+ // Accepted -> (recv ACK) -> Accepted
+ TSK_FSM_ADD_ALWAYS(_fsm_state_Accepted, _fsm_action_recv_ACK, _fsm_state_Accepted, tsip_transac_ist_Accepted_2_Accepted_iACK, "tsip_transac_ist_Accepted_2_Accepted_iACK"),
+ // Accepted -> (timerL) -> Terminated
+ TSK_FSM_ADD_ALWAYS(_fsm_state_Accepted, _fsm_action_timerL, _fsm_state_Terminated, tsip_transac_ist_Accepted_2_Terminated_timerL, "tsip_transac_ist_Accepted_2_Terminated_timerL"),
+
+ /*=======================
+ * === Confirmed ===
+ */
+ // Confirmed -> (timerI) -> Terminated
+ TSK_FSM_ADD_ALWAYS(_fsm_state_Confirmed, _fsm_action_timerI, _fsm_state_Terminated, tsip_transac_ist_Confirmed_2_Terminated_timerI, "tsip_transac_ist_Confirmed_2_Terminated_timerI"),
+
+
+ /*=======================
+ * === Any ===
+ */
+ // Any -> (transport error) -> Terminated
+ TSK_FSM_ADD_ALWAYS(tsk_fsm_state_any, _fsm_action_transporterror, _fsm_state_Terminated, tsip_transac_ist_Any_2_Terminated_X_transportError, "tsip_transac_ist_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_ist_Any_2_Terminated_X_Error, "tsip_transac_ist_Any_2_Terminated_X_Error"),
+ // Any -> (cancel) -> Terminated
+ TSK_FSM_ADD_ALWAYS(tsk_fsm_state_any, _fsm_action_cancel, _fsm_state_Terminated, tsip_transac_ist_Any_2_Terminated_X_cancel, "tsip_transac_ist_Any_2_Terminated_X_cancel"),
+
+
+ TSK_FSM_ADD_NULL());
+
+ /* Set callback function to call when new messages arrive or errors happen at
+ the transport layer.
+ */
+ TSIP_TRANSAC(self)->callback = TSIP_TRANSAC_EVENT_CALLBACK_F(tsip_transac_ist_event_callback);
+
+ /* Set Timers
+ * RFC 3261 17.2.1: For unreliable transports, timer G is set to fire in T1 seconds, and is not set to fire for
+ reliable transports.
+ */
+ self->timerH.timeout = TSIP_TIMER_GET(H);
+ self->timerG.timeout = TSIP_TIMER_GET(G);
+ self->timerL.timeout = TSIP_TIMER_GET(L);
+ self->timerX.timeout = TSIP_TIMER_GET(G);
+
+ return 0;
}
tsip_transac_ist_t* tsip_transac_ist_create(int32_t cseq_value, const char* callid, tsip_transac_dst_t* dst)
{
- tsip_transac_ist_t* transac = tsk_object_new(tsip_transac_ist_def_t);
- if(transac){
- // initialize base class
- tsip_transac_init(TSIP_TRANSAC(transac), tsip_transac_type_ist, cseq_value, "INVITE", callid, dst, _fsm_state_Started, _fsm_state_Terminated);
-
- // init FSM
- TSIP_TRANSAC_GET_FSM(transac)->debug = DEBUG_STATE_MACHINE;
- tsk_fsm_set_callback_terminated(TSIP_TRANSAC_GET_FSM(transac), TSK_FSM_ONTERMINATED_F(tsip_transac_ist_OnTerminated), (const void*)transac);
-
- // initialize IST object
- tsip_transac_ist_init(transac);
- }
- return transac;
+ tsip_transac_ist_t* transac = tsk_object_new(tsip_transac_ist_def_t);
+ if(transac) {
+ // initialize base class
+ tsip_transac_init(TSIP_TRANSAC(transac), tsip_transac_type_ist, cseq_value, "INVITE", callid, dst, _fsm_state_Started, _fsm_state_Terminated);
+
+ // init FSM
+ TSIP_TRANSAC_GET_FSM(transac)->debug = DEBUG_STATE_MACHINE;
+ tsk_fsm_set_callback_terminated(TSIP_TRANSAC_GET_FSM(transac), TSK_FSM_ONTERMINATED_F(tsip_transac_ist_OnTerminated), (const void*)transac);
+
+ // initialize IST object
+ tsip_transac_ist_init(transac);
+ }
+ return transac;
}
int tsip_transac_ist_start(tsip_transac_ist_t *self, const tsip_request_t* request)
{
- int ret = -1;
-
- if(self && !TSIP_TRANSAC(self)->running && request){
- TSIP_TRANSAC(self)->running = 1;
- if((ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_recv_INVITE, request))){
- //
- }
- }
- return ret;
+ int ret = -1;
+
+ if(self && !TSIP_TRANSAC(self)->running && request) {
+ TSIP_TRANSAC(self)->running = 1;
+ if((ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_recv_INVITE, request))) {
+ //
+ }
+ }
+ return ret;
}
@@ -369,286 +361,286 @@ int tsip_transac_ist_start(tsip_transac_ist_t *self, const tsip_request_t* reque
*/
int tsip_transac_ist_Started_2_Proceeding_X_INVITE(va_list *app)
{
- tsip_transac_ist_t *self = va_arg(*app, tsip_transac_ist_t *);
- const tsip_request_t *request = va_arg(*app, const tsip_request_t *);
- int ret = -1;
-
- if(TNET_SOCKET_TYPE_IS_VALID(request->src_net_type)){
- TSIP_TRANSAC(self)->reliable = TNET_SOCKET_TYPE_IS_STREAM(request->src_net_type);
- }
-
- /* Set Timers */
- self->timerI.timeout = TSIP_TRANSAC(self)->reliable ? 0 : TSIP_TIMER_GET(I);
-
- /* RFC 3261 - 17.2.1 INVITE Server Transaction
- When a server transaction is constructed for a request, it enters the
- "Proceeding" state. The server transaction MUST generate a 100
- (Trying) response unless it knows that the TU will generate a
- provisional or final response within 200 ms, in which case it MAY
- generate a 100 (Trying) response.
-
- RFC 3262 - 3. UAS Behavior
- A UAS MUST NOT attempt to send a 100 (Trying) response reliably.
- */
- if(request){
- tsip_response_t* response;
- if((response = tsip_response_new(100, "Trying (sent from the Transaction Layer)", request))){
- ret = tsip_transac_send(TSIP_TRANSAC(self), TSIP_TRANSAC(self)->branch, response);
- TRANSAC_IST_SET_LAST_RESPONSE(self, response); // Update last response
- TSK_OBJECT_SAFE_FREE(response);
- }
- }
- if(!ret){ /* Send "100 Trying" is OK ==> alert dialog for the incoming INVITE */
- ret = tsip_transac_deliver(TSIP_TRANSAC(self), tsip_dialog_i_msg, request);
- }
- return ret;
+ tsip_transac_ist_t *self = va_arg(*app, tsip_transac_ist_t *);
+ const tsip_request_t *request = va_arg(*app, const tsip_request_t *);
+ int ret = -1;
+
+ if(TNET_SOCKET_TYPE_IS_VALID(request->src_net_type)) {
+ TSIP_TRANSAC(self)->reliable = TNET_SOCKET_TYPE_IS_STREAM(request->src_net_type);
+ }
+
+ /* Set Timers */
+ self->timerI.timeout = TSIP_TRANSAC(self)->reliable ? 0 : TSIP_TIMER_GET(I);
+
+ /* RFC 3261 - 17.2.1 INVITE Server Transaction
+ When a server transaction is constructed for a request, it enters the
+ "Proceeding" state. The server transaction MUST generate a 100
+ (Trying) response unless it knows that the TU will generate a
+ provisional or final response within 200 ms, in which case it MAY
+ generate a 100 (Trying) response.
+
+ RFC 3262 - 3. UAS Behavior
+ A UAS MUST NOT attempt to send a 100 (Trying) response reliably.
+ */
+ if(request) {
+ tsip_response_t* response;
+ if((response = tsip_response_new(100, "Trying (sent from the Transaction Layer)", request))) {
+ ret = tsip_transac_send(TSIP_TRANSAC(self), TSIP_TRANSAC(self)->branch, response);
+ TRANSAC_IST_SET_LAST_RESPONSE(self, response); // Update last response
+ TSK_OBJECT_SAFE_FREE(response);
+ }
+ }
+ if(!ret) { /* Send "100 Trying" is OK ==> alert dialog for the incoming INVITE */
+ ret = tsip_transac_deliver(TSIP_TRANSAC(self), tsip_dialog_i_msg, request);
+ }
+ return ret;
}
/* Proceeding --> (recv INVITE) --> Proceeding
*/
int tsip_transac_ist_Proceeding_2_Proceeding_X_INVITE(va_list *app)
{
- tsip_transac_ist_t *self = va_arg(*app, tsip_transac_ist_t *);
- //const tsip_request_t *request = va_arg(*app, const tsip_request_t *);
- int ret = -1;
-
- /* RFC 3261 - 17.2.1 INVITE Server Transaction
- If a request retransmission is received while in the "Proceeding" state, the most
- recent provisional response that was received from the TU MUST be
- passed to the transport layer for retransmission.
- */
- if(self->lastResponse){
- ret = tsip_transac_send(TSIP_TRANSAC(self), TSIP_TRANSAC(self)->branch, self->lastResponse);
- }
-
- return ret;
+ tsip_transac_ist_t *self = va_arg(*app, tsip_transac_ist_t *);
+ //const tsip_request_t *request = va_arg(*app, const tsip_request_t *);
+ int ret = -1;
+
+ /* RFC 3261 - 17.2.1 INVITE Server Transaction
+ If a request retransmission is received while in the "Proceeding" state, the most
+ recent provisional response that was received from the TU MUST be
+ passed to the transport layer for retransmission.
+ */
+ if(self->lastResponse) {
+ ret = tsip_transac_send(TSIP_TRANSAC(self), TSIP_TRANSAC(self)->branch, self->lastResponse);
+ }
+
+ return ret;
}
/* Proceeding --> (send 1xx) --> Proceeding
*/
int tsip_transac_ist_Proceeding_2_Proceeding_X_1xx(va_list *app)
{
- tsip_transac_ist_t *self = va_arg(*app, tsip_transac_ist_t *);
- const tsip_response_t *response = va_arg(*app, const tsip_response_t *);
- int ret;
+ tsip_transac_ist_t *self = va_arg(*app, tsip_transac_ist_t *);
+ const tsip_response_t *response = va_arg(*app, const tsip_response_t *);
+ int ret;
- /* Send to the transport layer */
- ret = tsip_transac_send(TSIP_TRANSAC(self), TSIP_TRANSAC(self)->branch, TSIP_MESSAGE(response));
+ /* Send to the transport layer */
+ ret = tsip_transac_send(TSIP_TRANSAC(self), TSIP_TRANSAC(self)->branch, TSIP_MESSAGE(response));
- /* Update last response */
- TRANSAC_IST_SET_LAST_RESPONSE(self, response);
+ /* Update last response */
+ TRANSAC_IST_SET_LAST_RESPONSE(self, response);
- return ret;
+ return ret;
}
/* Proceeding --> (send 300-699) --> Completed
*/
int tsip_transac_ist_Proceeding_2_Completed_X_300_to_699(va_list *app)
{
- tsip_transac_ist_t *self = va_arg(*app, tsip_transac_ist_t *);
- const tsip_response_t *response = va_arg(*app, const tsip_response_t *);
- int ret;
-
- /* RFC 3264 17.2.1 INVITE Server Transaction
- While in the "Proceeding" state, if the TU passes a response with
- status code from 300 to 699 to the server transaction, the response
- MUST be passed to the transport layer for transmission, and the state
- machine MUST enter the "Completed" state. For unreliable transports, timer G is set to fire in T1 seconds,
- and is not set to fire for reliable transports.
- */
- if(!TSIP_TRANSAC(self)->reliable){
- TRANSAC_IST_TIMER_SCHEDULE(G);
- }
-
- /* Send to the transport layer */
- ret = tsip_transac_send(TSIP_TRANSAC(self), TSIP_TRANSAC(self)->branch, TSIP_MESSAGE(response));
-
- /* Update last response */
- TRANSAC_IST_SET_LAST_RESPONSE(self, response);
-
- /* RFC 3261 - 17.2.1 INVITE Server Transaction
- When the "Completed" state is entered, timer H MUST be set to fire in
- 64*T1 seconds for all transports.
- */
- TRANSAC_IST_TIMER_SCHEDULE(H);
-
- return ret;
+ tsip_transac_ist_t *self = va_arg(*app, tsip_transac_ist_t *);
+ const tsip_response_t *response = va_arg(*app, const tsip_response_t *);
+ int ret;
+
+ /* RFC 3264 17.2.1 INVITE Server Transaction
+ While in the "Proceeding" state, if the TU passes a response with
+ status code from 300 to 699 to the server transaction, the response
+ MUST be passed to the transport layer for transmission, and the state
+ machine MUST enter the "Completed" state. For unreliable transports, timer G is set to fire in T1 seconds,
+ and is not set to fire for reliable transports.
+ */
+ if(!TSIP_TRANSAC(self)->reliable) {
+ TRANSAC_IST_TIMER_SCHEDULE(G);
+ }
+
+ /* Send to the transport layer */
+ ret = tsip_transac_send(TSIP_TRANSAC(self), TSIP_TRANSAC(self)->branch, TSIP_MESSAGE(response));
+
+ /* Update last response */
+ TRANSAC_IST_SET_LAST_RESPONSE(self, response);
+
+ /* RFC 3261 - 17.2.1 INVITE Server Transaction
+ When the "Completed" state is entered, timer H MUST be set to fire in
+ 64*T1 seconds for all transports.
+ */
+ TRANSAC_IST_TIMER_SCHEDULE(H);
+
+ return ret;
}
/* Proceeding --> (send 2xx) --> Accepted
*/
int tsip_transac_ist_Proceeding_2_Accepted_X_2xx(va_list *app)
{
- tsip_transac_ist_t *self = va_arg(*app, tsip_transac_ist_t *);
- const tsip_response_t *response = va_arg(*app, const tsip_response_t *);
- int ret = -1;
-
- /* draft-sparks-sip-invfix-03 - 8.5. Pages 134 to 135
- If, while in the "Proceeding" state, the TU passes a 2xx response
- to the server transaction, the server transaction MUST pass this
- response to the transport layer for transmission. It is not
- retransmitted by the server transaction; retransmissions of 2xx
- responses are handled by the TU. The server transaction MUST then
- transition to the "Accepted" state.
- */
- ret = tsip_transac_send(TSIP_TRANSAC(self), TSIP_TRANSAC(self)->branch, TSIP_MESSAGE(response));
-
- /* Update last response */
- TRANSAC_IST_SET_LAST_RESPONSE(self, response);
-
- /* RFC 3261 - 13.3.1.4 The INVITE is Accepted
- Since 2xx is retransmitted end-to-end, there may be hops between
- UAS and UAC that are UDP. To ensure reliable delivery across
- these hops, the response is retransmitted periodically even if the
- transport at the UAS is reliable.
- */
- TRANSAC_IST_TIMER_SCHEDULE(X);
- self->timerX.timeout <<= 1;
-
- /* draft-sparks-sip-invfix-03 - 8.7. Page 137
- When the INVITE server transaction enters the "Accepted" state,
- Timer L MUST be set to fire in 64*T1 for all transports. This
- value matches both Timer B in the next upstream client state
- machine (the amount of time the previous hop will wait for a
- response when no provisionals have been sent) and the amount of
- time this (or any downstream) UAS core might be retransmitting the
- 2xx while waiting for an ACK.
- */
- TRANSAC_IST_TIMER_SCHEDULE(L);
-
- return ret;
+ tsip_transac_ist_t *self = va_arg(*app, tsip_transac_ist_t *);
+ const tsip_response_t *response = va_arg(*app, const tsip_response_t *);
+ int ret = -1;
+
+ /* draft-sparks-sip-invfix-03 - 8.5. Pages 134 to 135
+ If, while in the "Proceeding" state, the TU passes a 2xx response
+ to the server transaction, the server transaction MUST pass this
+ response to the transport layer for transmission. It is not
+ retransmitted by the server transaction; retransmissions of 2xx
+ responses are handled by the TU. The server transaction MUST then
+ transition to the "Accepted" state.
+ */
+ ret = tsip_transac_send(TSIP_TRANSAC(self), TSIP_TRANSAC(self)->branch, TSIP_MESSAGE(response));
+
+ /* Update last response */
+ TRANSAC_IST_SET_LAST_RESPONSE(self, response);
+
+ /* RFC 3261 - 13.3.1.4 The INVITE is Accepted
+ Since 2xx is retransmitted end-to-end, there may be hops between
+ UAS and UAC that are UDP. To ensure reliable delivery across
+ these hops, the response is retransmitted periodically even if the
+ transport at the UAS is reliable.
+ */
+ TRANSAC_IST_TIMER_SCHEDULE(X);
+ self->timerX.timeout <<= 1;
+
+ /* draft-sparks-sip-invfix-03 - 8.7. Page 137
+ When the INVITE server transaction enters the "Accepted" state,
+ Timer L MUST be set to fire in 64*T1 for all transports. This
+ value matches both Timer B in the next upstream client state
+ machine (the amount of time the previous hop will wait for a
+ response when no provisionals have been sent) and the amount of
+ time this (or any downstream) UAS core might be retransmitting the
+ 2xx while waiting for an ACK.
+ */
+ TRANSAC_IST_TIMER_SCHEDULE(L);
+
+ return ret;
}
/* Completed --> (recv INVITE) --> Completed
*/
int tsip_transac_ist_Completed_2_Completed_INVITE(va_list *app)
{
- tsip_transac_ist_t *self = va_arg(*app, tsip_transac_ist_t *);
- //const tsip_message_t *message = va_arg(*app, const tsip_message_t *);
- int ret = -1;
-
- /* RFC 3261 - 17.2.1 INVITE Server Transaction
- Furthermore, while in the "Completed" state, if a request retransmission is
- received, the server SHOULD pass the response to the transport for
- retransmission.
- */
- if(self->lastResponse){
- ret = tsip_transac_send(TSIP_TRANSAC(self), TSIP_TRANSAC(self)->branch, self->lastResponse);
- }
-
- return ret;
+ tsip_transac_ist_t *self = va_arg(*app, tsip_transac_ist_t *);
+ //const tsip_message_t *message = va_arg(*app, const tsip_message_t *);
+ int ret = -1;
+
+ /* RFC 3261 - 17.2.1 INVITE Server Transaction
+ Furthermore, while in the "Completed" state, if a request retransmission is
+ received, the server SHOULD pass the response to the transport for
+ retransmission.
+ */
+ if(self->lastResponse) {
+ ret = tsip_transac_send(TSIP_TRANSAC(self), TSIP_TRANSAC(self)->branch, self->lastResponse);
+ }
+
+ return ret;
}
/* Completed --> (timerG) --> Completed
*/
int tsip_transac_ist_Completed_2_Completed_timerG(va_list *app)
{
- tsip_transac_ist_t *self = va_arg(*app, tsip_transac_ist_t *);
- //const tsip_message_t *message = va_arg(*app, const tsip_message_t *);
- int ret = -1;
-
- /* RFC 3261 - 17.2.1 INVITE Server Transaction
- If timer G fires, the response is passed to the transport layer once
- more for retransmission, and timer G is set to fire in MIN(2*T1, T2) seconds.
- From then on, when timer G fires, the response is passed to the transport again for
- transmission, and timer G is reset with a value that doubles, unless
- that value exceeds T2, in which case it is reset with the value of T2.
- */
- if(self->lastResponse){
- ret = tsip_transac_send(TSIP_TRANSAC(self), TSIP_TRANSAC(self)->branch, self->lastResponse);
- }
- self->timerG.timeout = TSK_MIN(self->timerG.timeout*2, TSIP_TIMER_GET(T2));
- TRANSAC_IST_TIMER_SCHEDULE(G);
-
- return ret;
+ tsip_transac_ist_t *self = va_arg(*app, tsip_transac_ist_t *);
+ //const tsip_message_t *message = va_arg(*app, const tsip_message_t *);
+ int ret = -1;
+
+ /* RFC 3261 - 17.2.1 INVITE Server Transaction
+ If timer G fires, the response is passed to the transport layer once
+ more for retransmission, and timer G is set to fire in MIN(2*T1, T2) seconds.
+ From then on, when timer G fires, the response is passed to the transport again for
+ transmission, and timer G is reset with a value that doubles, unless
+ that value exceeds T2, in which case it is reset with the value of T2.
+ */
+ if(self->lastResponse) {
+ ret = tsip_transac_send(TSIP_TRANSAC(self), TSIP_TRANSAC(self)->branch, self->lastResponse);
+ }
+ self->timerG.timeout = TSK_MIN(self->timerG.timeout*2, TSIP_TIMER_GET(T2));
+ TRANSAC_IST_TIMER_SCHEDULE(G);
+
+ return ret;
}
/* Completed --> (timerH) --> Terminated
*/
int tsip_transac_ist_Completed_2_Terminated_timerH(va_list *app)
{
- tsip_transac_ist_t *self = va_arg(*app, tsip_transac_ist_t *);
- //const tsip_message_t *message = va_arg(*app, const tsip_message_t *);
-
- /* RFC 3261 - 17.2.1 INVITE Server Transaction
- If timer H fires while in the "Completed" state, it implies that the
- ACK was never received. In this case, the server transaction MUST
- transition to the "Terminated" state, and MUST indicate to the TU
- that a transaction failure has occurred.
- */
- return tsip_transac_deliver(TSIP_TRANSAC(self), tsip_dialog_transport_error, tsk_null);
+ tsip_transac_ist_t *self = va_arg(*app, tsip_transac_ist_t *);
+ //const tsip_message_t *message = va_arg(*app, const tsip_message_t *);
+
+ /* RFC 3261 - 17.2.1 INVITE Server Transaction
+ If timer H fires while in the "Completed" state, it implies that the
+ ACK was never received. In this case, the server transaction MUST
+ transition to the "Terminated" state, and MUST indicate to the TU
+ that a transaction failure has occurred.
+ */
+ return tsip_transac_deliver(TSIP_TRANSAC(self), tsip_dialog_transport_error, tsk_null);
}
/* Completed --> (recv ACK) --> Confirmed
*/
int tsip_transac_ist_Completed_2_Confirmed_ACK(va_list *app)
{
- tsip_transac_ist_t *self = va_arg(*app, tsip_transac_ist_t *);
- //const tsip_message_t *message = va_arg(*app, const tsip_message_t *);
-
- /* RFC 3261 - 17.2.1 INVITE Server Transaction
- If an ACK is received while the server transaction is in the
- "Completed" state, the server transaction MUST transition to the
- "Confirmed" state. As Timer G is ignored in this state, any
- retransmissions of the response will cease
- */
- TRANSAC_TIMER_CANCEL(G);/* To avoid warnings from FSM manager. */
-
- /* RFC 3261 - 17.2.1 INVITE Server Transaction
- The purpose of the "Confirmed" state is to absorb any additional ACK
- messages that arrive, triggered from retransmissions of the final
- response. When this state is entered, timer I is set to fire in T4
- seconds for unreliable transports, and zero seconds for reliable
- transports.
- */
- TRANSAC_IST_TIMER_SCHEDULE(I); /* Has the right value (zero of reliable and ...) */
-
-
- return 0;
+ tsip_transac_ist_t *self = va_arg(*app, tsip_transac_ist_t *);
+ //const tsip_message_t *message = va_arg(*app, const tsip_message_t *);
+
+ /* RFC 3261 - 17.2.1 INVITE Server Transaction
+ If an ACK is received while the server transaction is in the
+ "Completed" state, the server transaction MUST transition to the
+ "Confirmed" state. As Timer G is ignored in this state, any
+ retransmissions of the response will cease
+ */
+ TRANSAC_TIMER_CANCEL(G);/* To avoid warnings from FSM manager. */
+
+ /* RFC 3261 - 17.2.1 INVITE Server Transaction
+ The purpose of the "Confirmed" state is to absorb any additional ACK
+ messages that arrive, triggered from retransmissions of the final
+ response. When this state is entered, timer I is set to fire in T4
+ seconds for unreliable transports, and zero seconds for reliable
+ transports.
+ */
+ TRANSAC_IST_TIMER_SCHEDULE(I); /* Has the right value (zero of reliable and ...) */
+
+
+ return 0;
}
/* Accepted --> (recv INVITE) --> Accepted
*/
int tsip_transac_ist_Accepted_2_Accepted_INVITE(va_list *app)
{
- tsip_transac_ist_t *self = va_arg(*app, tsip_transac_ist_t *);
-
- /* draft-sparks-sip-invfix-03 - 8.7. Page 137
- The purpose of the "Accepted" state is to absorb retransmissions
- of an accepted INVITE request. Any such retransmissions are
- absorbed entirely within the server transaction. They are not
- passed up to the TU since any downstream UAS cores that accepted
- the request have taken responsibility for reliability and will
- already retransmit their 2xx responses if neccessary.
- */
-
- /* Do not pass to the TU (see above)
- VERY IMPORTANT: INVITE dialog is responsible for reliability of the 2xx response.
- */
- if(self->lastResponse){
- return tsip_transac_send(TSIP_TRANSAC(self), TSIP_TRANSAC(self)->branch, self->lastResponse);
- }
- return 0;
+ tsip_transac_ist_t *self = va_arg(*app, tsip_transac_ist_t *);
+
+ /* draft-sparks-sip-invfix-03 - 8.7. Page 137
+ The purpose of the "Accepted" state is to absorb retransmissions
+ of an accepted INVITE request. Any such retransmissions are
+ absorbed entirely within the server transaction. They are not
+ passed up to the TU since any downstream UAS cores that accepted
+ the request have taken responsibility for reliability and will
+ already retransmit their 2xx responses if neccessary.
+ */
+
+ /* Do not pass to the TU (see above)
+ VERY IMPORTANT: INVITE dialog is responsible for reliability of the 2xx response.
+ */
+ if(self->lastResponse) {
+ return tsip_transac_send(TSIP_TRANSAC(self), TSIP_TRANSAC(self)->branch, self->lastResponse);
+ }
+ return 0;
}
/* Accepted --> (send 2xx) --> Accepted
*/
int tsip_transac_ist_Accepted_2_Accepted_2xx(va_list *app)
{
- tsip_transac_ist_t *self = va_arg(*app, tsip_transac_ist_t *);
- const tsip_response_t *response = va_arg(*app, const tsip_response_t *);
- int ret;
- /* draft-sparks-sip-invfix-03 - 8.7. Page 137
- While in the "Accepted" state, if the TU passes a 2xx response,
- the server transaction MUST pass the response to the transport
- layer for transmission.
- */
- ret = tsip_transac_send(TSIP_TRANSAC(self), TSIP_TRANSAC(self)->branch, TSIP_MESSAGE(response));
-
- /* Update last response */
- TRANSAC_IST_SET_LAST_RESPONSE(self, response);
-
- return ret;
+ tsip_transac_ist_t *self = va_arg(*app, tsip_transac_ist_t *);
+ const tsip_response_t *response = va_arg(*app, const tsip_response_t *);
+ int ret;
+ /* draft-sparks-sip-invfix-03 - 8.7. Page 137
+ While in the "Accepted" state, if the TU passes a 2xx response,
+ the server transaction MUST pass the response to the transport
+ layer for transmission.
+ */
+ ret = tsip_transac_send(TSIP_TRANSAC(self), TSIP_TRANSAC(self)->branch, TSIP_MESSAGE(response));
+
+ /* Update last response */
+ TRANSAC_IST_SET_LAST_RESPONSE(self, response);
+
+ return ret;
}
/* Accepted --> (timer X) --> Accepted
@@ -656,14 +648,14 @@ int tsip_transac_ist_Accepted_2_Accepted_2xx(va_list *app)
*/
static int tsip_transac_ist_Accepted_2_Accepted_timerX(va_list *app)
{
- tsip_transac_ist_t *self = va_arg(*app, tsip_transac_ist_t *);
- if(self->lastResponse){
- int ret;
- ret = tsip_transac_send(TSIP_TRANSAC(self), TSIP_TRANSAC(self)->branch, self->lastResponse);
- self->timerX.timeout <<= 1;
- TRANSAC_IST_TIMER_SCHEDULE(X);
- }
- return 0;
+ tsip_transac_ist_t *self = va_arg(*app, tsip_transac_ist_t *);
+ if(self->lastResponse) {
+ int ret;
+ ret = tsip_transac_send(TSIP_TRANSAC(self), TSIP_TRANSAC(self)->branch, self->lastResponse);
+ self->timerX.timeout <<= 1;
+ TRANSAC_IST_TIMER_SCHEDULE(X);
+ }
+ return 0;
}
/* Accepted --> (Recv ACK) --> Accepted
@@ -671,77 +663,77 @@ static int tsip_transac_ist_Accepted_2_Accepted_timerX(va_list *app)
*/
int tsip_transac_ist_Accepted_2_Accepted_iACK(va_list *app)
{
- tsip_transac_ist_t *self = va_arg(*app, tsip_transac_ist_t *);
- const tsip_request_t *request = va_arg(*app, const tsip_request_t *);
- self->acked = tsk_true;
- TRANSAC_TIMER_CANCEL(X);
- return tsip_transac_deliver(TSIP_TRANSAC(self), tsip_dialog_i_msg, request);
+ tsip_transac_ist_t *self = va_arg(*app, tsip_transac_ist_t *);
+ const tsip_request_t *request = va_arg(*app, const tsip_request_t *);
+ self->acked = tsk_true;
+ TRANSAC_TIMER_CANCEL(X);
+ return tsip_transac_deliver(TSIP_TRANSAC(self), tsip_dialog_i_msg, request);
}
/* Accepted --> (timerL) --> Terminated
*/
static int tsip_transac_ist_Accepted_2_Terminated_timerL(va_list *app)
{
- tsip_transac_ist_t *self = va_arg(*app, tsip_transac_ist_t *);
- //const tsip_message_t *message = va_arg(*app, const tsip_message_t *);
-
- /* draft-sparks-sip-invfix-03 - 8.7. Page 137
- If Timer L fires while the INVITE server transaction is in the "Accepted" state, the transaction
- MUST transition to the "Terminated" state. Once the transaction is in the "Terminated" state, it MUST be
- destroyed immediately.
- */
- if(!self->acked){
- TSK_DEBUG_ERROR("ACK not received");
- return tsip_transac_deliver(TSIP_TRANSAC(self), tsip_dialog_transport_error, tsk_null);
- }
- return 0;
+ tsip_transac_ist_t *self = va_arg(*app, tsip_transac_ist_t *);
+ //const tsip_message_t *message = va_arg(*app, const tsip_message_t *);
+
+ /* draft-sparks-sip-invfix-03 - 8.7. Page 137
+ If Timer L fires while the INVITE server transaction is in the "Accepted" state, the transaction
+ MUST transition to the "Terminated" state. Once the transaction is in the "Terminated" state, it MUST be
+ destroyed immediately.
+ */
+ if(!self->acked) {
+ TSK_DEBUG_ERROR("ACK not received");
+ return tsip_transac_deliver(TSIP_TRANSAC(self), tsip_dialog_transport_error, tsk_null);
+ }
+ return 0;
}
/* Confirmed --> (timerI) --> Terminated
*/
static int tsip_transac_ist_Confirmed_2_Terminated_timerI(va_list *app)
{
- /* RFC 3261 - 17.2.1 INVITE Server Transaction
- Once timer I fires, the server MUST transition to the
- "Terminated" state.
-
- Once the transaction is in the "Terminated" state, it MUST be
- destroyed immediately. As with client transactions, this is needed
- to ensure reliability of the 2xx responses to INVITE.
- */
- return 0;
+ /* RFC 3261 - 17.2.1 INVITE Server Transaction
+ Once timer I fires, the server MUST transition to the
+ "Terminated" state.
+
+ Once the transaction is in the "Terminated" state, it MUST be
+ destroyed immediately. As with client transactions, this is needed
+ to ensure reliability of the 2xx responses to INVITE.
+ */
+ return 0;
}
/* Any -> (Transport Error) -> Terminated
*/
static int tsip_transac_ist_Any_2_Terminated_X_transportError(va_list *app)
{
- tsip_transac_ist_t *self = va_arg(*app, tsip_transac_ist_t *);
- //const tsip_message_t *message = va_arg(*app, const tsip_message_t *);
+ tsip_transac_ist_t *self = va_arg(*app, tsip_transac_ist_t *);
+ //const tsip_message_t *message = va_arg(*app, const tsip_message_t *);
- /* Timers will be canceled by "tsip_transac_nict_OnTerminated" */
+ /* Timers will be canceled by "tsip_transac_nict_OnTerminated" */
- return tsip_transac_deliver(TSIP_TRANSAC(self), tsip_dialog_transport_error, tsk_null);
+ return tsip_transac_deliver(TSIP_TRANSAC(self), tsip_dialog_transport_error, tsk_null);
}
/* Any -> (Error) -> Terminated
*/
static int tsip_transac_ist_Any_2_Terminated_X_Error(va_list *app)
{
- tsip_transac_ist_t *self = va_arg(*app, tsip_transac_ist_t *);
- //const tsip_message_t *message = va_arg(*app, const tsip_message_t *);
+ tsip_transac_ist_t *self = va_arg(*app, tsip_transac_ist_t *);
+ //const tsip_message_t *message = va_arg(*app, const tsip_message_t *);
- /* Timers will be canceled by "tsip_transac_nict_OnTerminated" */
+ /* Timers will be canceled by "tsip_transac_nict_OnTerminated" */
- return tsip_transac_deliver(TSIP_TRANSAC(self), tsip_dialog_error, tsk_null);
+ return tsip_transac_deliver(TSIP_TRANSAC(self), tsip_dialog_error, tsk_null);
}
/* Any -> (cancel) -> Terminated
*/
static int tsip_transac_ist_Any_2_Terminated_X_cancel(va_list *app)
{
- /* doubango-specific */
- return 0;
+ /* doubango-specific */
+ return 0;
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++
@@ -754,10 +746,10 @@ static int tsip_transac_ist_Any_2_Terminated_X_cancel(va_list *app)
*/
static int tsip_transac_ist_OnTerminated(tsip_transac_ist_t *self)
{
- TSK_DEBUG_INFO("=== IST terminated ===");
-
- /* Remove (and destroy) the transaction from the layer. */
- return tsip_transac_remove(TSIP_TRANSAC(self));
+ TSK_DEBUG_INFO("=== IST terminated ===");
+
+ /* Remove (and destroy) the transaction from the layer. */
+ return tsip_transac_remove(TSIP_TRANSAC(self));
}
@@ -777,47 +769,45 @@ static int tsip_transac_ist_OnTerminated(tsip_transac_ist_t *self)
//
static tsk_object_t* tsip_transac_ist_ctor(tsk_object_t * self, va_list * app)
{
- tsip_transac_ist_t *transac = self;
- if(transac){
- }
- return self;
+ tsip_transac_ist_t *transac = self;
+ if(transac) {
+ }
+ return self;
}
static tsk_object_t* tsip_transac_ist_dtor(tsk_object_t * _self)
-{
- tsip_transac_ist_t *self = _self;
- if(self)
- {
- /* Cancel timers */
- TRANSAC_TIMER_CANCEL(H);
- TRANSAC_TIMER_CANCEL(I);
- if(!TSIP_TRANSAC(self)->reliable){
- TRANSAC_TIMER_CANCEL(G);
- }
- TRANSAC_TIMER_CANCEL(L);
- TRANSAC_TIMER_CANCEL(X);
-
- TSIP_TRANSAC(self)->running = tsk_false;
- TSK_OBJECT_SAFE_FREE(self->lastResponse);
-
- /* DeInitialize base class */
- tsip_transac_deinit(TSIP_TRANSAC(self));
-
- TSK_DEBUG_INFO("*** IST destroyed ***");
- }
- return _self;
+{
+ tsip_transac_ist_t *self = _self;
+ if(self) {
+ /* Cancel timers */
+ TRANSAC_TIMER_CANCEL(H);
+ TRANSAC_TIMER_CANCEL(I);
+ if(!TSIP_TRANSAC(self)->reliable) {
+ TRANSAC_TIMER_CANCEL(G);
+ }
+ TRANSAC_TIMER_CANCEL(L);
+ TRANSAC_TIMER_CANCEL(X);
+
+ TSIP_TRANSAC(self)->running = tsk_false;
+ TSK_OBJECT_SAFE_FREE(self->lastResponse);
+
+ /* DeInitialize base class */
+ tsip_transac_deinit(TSIP_TRANSAC(self));
+
+ TSK_DEBUG_INFO("*** IST destroyed ***");
+ }
+ return _self;
}
static int tsip_transac_ist_cmp(const tsk_object_t *t1, const tsk_object_t *t2)
{
- return tsip_transac_cmp(t1, t2);
+ return tsip_transac_cmp(t1, t2);
}
-static const tsk_object_def_t tsip_transac_ist_def_s =
-{
- sizeof(tsip_transac_ist_t),
- tsip_transac_ist_ctor,
- tsip_transac_ist_dtor,
- tsip_transac_ist_cmp,
+static const tsk_object_def_t tsip_transac_ist_def_s = {
+ sizeof(tsip_transac_ist_t),
+ tsip_transac_ist_ctor,
+ tsip_transac_ist_dtor,
+ tsip_transac_ist_cmp,
};
const tsk_object_def_t *tsip_transac_ist_def_t = &tsip_transac_ist_def_s;
diff --git a/tinySIP/src/transactions/tsip_transac_layer.c b/tinySIP/src/transactions/tsip_transac_layer.c
index b3cf167..767dfb6 100755
--- a/tinySIP/src/transactions/tsip_transac_layer.c
+++ b/tinySIP/src/transactions/tsip_transac_layer.c
@@ -2,19 +2,19 @@
* Copyright (C) 2010-2011 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -39,220 +39,215 @@
tsip_transac_layer_t* tsip_transac_layer_create(tsip_stack_t* stack)
{
- return tsk_object_new(tsip_transac_layer_def_t, stack);
+ return tsk_object_new(tsip_transac_layer_def_t, stack);
}
tsip_transac_t* tsip_transac_layer_new(const tsip_transac_layer_t *self, tsk_bool_t isCT, const tsip_message_t* msg, tsip_transac_dst_t* dst)
{
- tsip_transac_t *ret = tsk_null;
- tsip_transac_t *transac = tsk_null;
-
- tsk_safeobj_lock(self);
-
- if(self && msg)
- {
- if(TSIP_MESSAGE_IS_REQUEST(msg))
- {
- if(isCT) /* Client transaction */
- {
- if(TSIP_REQUEST_IS_INVITE(msg)){
- // INVITE Client transaction (ICT)
- transac = (tsip_transac_t *)tsip_transac_ict_create(msg->CSeq->seq, msg->Call_ID->value, dst);
- }
- else{
- // NON-INVITE Client transaction (NICT)
- transac = (tsip_transac_t *)tsip_transac_nict_create(msg->CSeq->seq, msg->CSeq->method, msg->Call_ID->value, dst);
- }
- }
- else /* Server transaction */
- {
- if(TSIP_REQUEST_IS_INVITE(msg)){
- // INVITE Server transaction (IST)
- transac = (tsip_transac_t *)tsip_transac_ist_create(msg->CSeq->seq, msg->Call_ID->value, dst);
- }
- else{
- // NON-INVITE Server transaction (NIST)
- transac = (tsip_transac_t *)tsip_transac_nist_create(msg->CSeq->seq, msg->CSeq->method, msg->Call_ID->value, dst);
- }
-
- if(transac){ /* Copy branch from the message */
- transac->branch = tsk_strdup(msg->firstVia->branch);
- }
- }
-
- /* Add new transaction */
- if(transac){
- ret = tsk_object_ref(transac);
- tsk_list_push_back_data(self->transactions, (void**)&transac);
- }
- }
- }
-
- tsk_safeobj_unlock(self);
-
- return ret;
+ tsip_transac_t *ret = tsk_null;
+ tsip_transac_t *transac = tsk_null;
+
+ tsk_safeobj_lock(self);
+
+ if(self && msg) {
+ if(TSIP_MESSAGE_IS_REQUEST(msg)) {
+ if(isCT) { /* Client transaction */
+ if(TSIP_REQUEST_IS_INVITE(msg)) {
+ // INVITE Client transaction (ICT)
+ transac = (tsip_transac_t *)tsip_transac_ict_create(msg->CSeq->seq, msg->Call_ID->value, dst);
+ }
+ else {
+ // NON-INVITE Client transaction (NICT)
+ transac = (tsip_transac_t *)tsip_transac_nict_create(msg->CSeq->seq, msg->CSeq->method, msg->Call_ID->value, dst);
+ }
+ }
+ else { /* Server transaction */
+ if(TSIP_REQUEST_IS_INVITE(msg)) {
+ // INVITE Server transaction (IST)
+ transac = (tsip_transac_t *)tsip_transac_ist_create(msg->CSeq->seq, msg->Call_ID->value, dst);
+ }
+ else {
+ // NON-INVITE Server transaction (NIST)
+ transac = (tsip_transac_t *)tsip_transac_nist_create(msg->CSeq->seq, msg->CSeq->method, msg->Call_ID->value, dst);
+ }
+
+ if(transac) { /* Copy branch from the message */
+ transac->branch = tsk_strdup(msg->firstVia->branch);
+ }
+ }
+
+ /* Add new transaction */
+ if(transac) {
+ ret = tsk_object_ref(transac);
+ tsk_list_push_back_data(self->transactions, (void**)&transac);
+ }
+ }
+ }
+
+ tsk_safeobj_unlock(self);
+
+ return ret;
}
int tsip_transac_layer_remove(tsip_transac_layer_t *self, const tsip_transac_t *transac)
{
- if(transac && self){
- tsk_safeobj_lock(self);
- tsk_list_remove_item_by_data(self->transactions, transac);
- tsk_safeobj_unlock(self);
+ if(transac && self) {
+ tsk_safeobj_lock(self);
+ tsk_list_remove_item_by_data(self->transactions, transac);
+ tsk_safeobj_unlock(self);
- return 0;
- }
+ return 0;
+ }
- return -1;
+ return -1;
}
/* cancel all transactions related to this dialog */
int tsip_transac_layer_cancel_by_dialog(tsip_transac_layer_t *self, const struct tsip_dialog_s* dialog)
{
- tsk_list_item_t *item;
- int ret = 0; /* Perhaps there is zero transaction */
+ tsk_list_item_t *item;
+ int ret = 0; /* Perhaps there is zero transaction */
- if(!self || !dialog){
- TSK_DEBUG_WARN("Invalid parameter.");
- return -1;
- }
-
- tsk_safeobj_lock(self);
+ if(!self || !dialog) {
+ TSK_DEBUG_WARN("Invalid parameter.");
+ return -1;
+ }
+
+ tsk_safeobj_lock(self);
again:
- tsk_list_foreach(item, self->transactions){
- if(tsk_object_cmp(dialog, TSIP_TRANSAC_GET_DIALOG(item->data)) == 0){
- if((ret = tsip_transac_fsm_act(TSIP_TRANSAC(item->data), tsip_atype_cancel, tsk_null))){ /* will call tsip_transac_layer_remove() if succeed */
- /* break; */
- }
- else{
- /* we cannot continue because an item has been removed from the list while we are looping through */
- goto again;
- }
- }
- }
- tsk_safeobj_unlock(self);
-
- return 0;
+ tsk_list_foreach(item, self->transactions) {
+ if(tsk_object_cmp(dialog, TSIP_TRANSAC_GET_DIALOG(item->data)) == 0) {
+ if((ret = tsip_transac_fsm_act(TSIP_TRANSAC(item->data), tsip_atype_cancel, tsk_null))) { /* will call tsip_transac_layer_remove() if succeed */
+ /* break; */
+ }
+ else {
+ /* we cannot continue because an item has been removed from the list while we are looping through */
+ goto again;
+ }
+ }
+ }
+ tsk_safeobj_unlock(self);
+
+ return 0;
}
tsip_transac_t* tsip_transac_layer_find_client(const tsip_transac_layer_t *self, const tsip_response_t* response)
{
- /*
- RFC 3261 - 17.1.3 Matching Responses to Client Transactions
-
- When the transport layer in the client receives a response, it has to
- determine which client transaction will handle the response, so that
- the processing of Sections 17.1.1 and 17.1.2 can take place. The
- branch parameter in the top Via header field is used for this
- purpose. A response matches a client transaction under two
- conditions:
-
- 1. If the response has the same value of the branch parameter in
- the top Via header field as the branch parameter in the top
- Via header field of the request that created the transaction.
-
- 2. If the method parameter in the CSeq header field matches the
- method of the request that created the transaction. The
- method is needed since a CANCEL request constitutes a
- different transaction, but shares the same value of the branch
- parameter.
- */
- tsip_transac_t *ret = tsk_null;
- tsip_transac_t *transac;
- tsk_list_item_t *item;
-
- /* Check first Via/CSeq validity.
- */
- if(!response->firstVia || !response->CSeq){
- return tsk_null;
- }
-
- tsk_safeobj_lock(self);
-
- tsk_list_foreach(item, self->transactions){
- transac = item->data;
- if( tsk_strequals(transac->branch, response->firstVia->branch)
- && tsk_strequals(transac->cseq_method, response->CSeq->method)
- )
- {
- ret = tsk_object_ref(transac);
- break;
- }
- }
-
- tsk_safeobj_unlock(self);
-
- return ret;
+ /*
+ RFC 3261 - 17.1.3 Matching Responses to Client Transactions
+
+ When the transport layer in the client receives a response, it has to
+ determine which client transaction will handle the response, so that
+ the processing of Sections 17.1.1 and 17.1.2 can take place. The
+ branch parameter in the top Via header field is used for this
+ purpose. A response matches a client transaction under two
+ conditions:
+
+ 1. If the response has the same value of the branch parameter in
+ the top Via header field as the branch parameter in the top
+ Via header field of the request that created the transaction.
+
+ 2. If the method parameter in the CSeq header field matches the
+ method of the request that created the transaction. The
+ method is needed since a CANCEL request constitutes a
+ different transaction, but shares the same value of the branch
+ parameter.
+ */
+ tsip_transac_t *ret = tsk_null;
+ tsip_transac_t *transac;
+ tsk_list_item_t *item;
+
+ /* Check first Via/CSeq validity.
+ */
+ if(!response->firstVia || !response->CSeq) {
+ return tsk_null;
+ }
+
+ tsk_safeobj_lock(self);
+
+ tsk_list_foreach(item, self->transactions) {
+ transac = item->data;
+ if( tsk_strequals(transac->branch, response->firstVia->branch)
+ && tsk_strequals(transac->cseq_method, response->CSeq->method)
+ ) {
+ ret = tsk_object_ref(transac);
+ break;
+ }
+ }
+
+ tsk_safeobj_unlock(self);
+
+ return ret;
}
tsip_transac_t* tsip_transac_layer_find_server(const tsip_transac_layer_t *self, const tsip_message_t* message)
{
- /*
- RFC 3261 - 17.2.3 Matching Requests to Server Transactions
-
- When a request is received from the network by the server, it has to
- be matched to an existing transaction. This is accomplished in the
- following manner.
-
- The branch parameter in the topmost Via header field of the request
- is examined. If it is present and begins with the magic cookie
- "z9hG4bK", the request was generated by a client transaction
- compliant to this specification. Therefore, the branch parameter
- will be unique across all transactions sent by that client. The
- request matches a transaction if:
-
- 1. the branch parameter in the request is equal to the one in the
- top Via header field of the request that created the
- transaction, and
-
- 2. the sent-by value in the top Via of the request is equal to the
- one in the request that created the transaction, and
-
- 3. the method of the request matches the one that created the
- transaction, except for ACK, where the method of the request
- that created the transaction is INVITE.
- */
- tsip_transac_t *ret = tsk_null;
- tsip_transac_t *transac;
- tsk_list_item_t *item;
- //const char* sent_by;
-
- /* Check first Via/CSeq validity */
- if(!message->firstVia || !message->CSeq){
- return tsk_null;
- }
-
- tsk_safeobj_lock(self);
-
- tsk_list_foreach(item, self->transactions){
- transac = item->data;
- if(TSIP_REQUEST_IS_ACK(message) && tsk_strequals(transac->callid, message->Call_ID->value)){ /* 1. ACK branch won't match INVITE's but they MUST have the same CSeq/CallId values */
- // [transac->type == tsip_transac_type_ist] is used to avoid looping in webrtc2sip mode (e.g. browser <->(breaker)<->browser)
- // (browser-1) -> INVITE -> (breaker) -> INVITE - (server) -> INVITE -> (breaker) -> (browser-2)
- // the breaker will have two transactions (IST and ICT) with same cseq value and call-id (if not changed by the server)
- if(transac->type == tsip_transac_type_ist && tsk_striequals(transac->cseq_method, "INVITE") && message->CSeq->seq == transac->cseq_value){
- ret = tsk_object_ref(transac);
- break;
- }
- }
- else if(tsk_strequals(transac->branch, message->firstVia->branch) /* 2. Compare branches*/
- && (1 == 1) /* FIXME: compare host:ip */
- ){
- if(tsk_strequals(transac->cseq_method, message->CSeq->method)){
- ret = tsk_object_ref(transac);
- break;
- }
- else if(TSIP_REQUEST_IS_CANCEL(message) || TSIP_RESPONSE_IS_TO_CANCEL(message)){
- ret = tsk_object_ref(transac);
- break;
- }
- }
- }
-
- tsk_safeobj_unlock(self);
-
- return ret;
+ /*
+ RFC 3261 - 17.2.3 Matching Requests to Server Transactions
+
+ When a request is received from the network by the server, it has to
+ be matched to an existing transaction. This is accomplished in the
+ following manner.
+
+ The branch parameter in the topmost Via header field of the request
+ is examined. If it is present and begins with the magic cookie
+ "z9hG4bK", the request was generated by a client transaction
+ compliant to this specification. Therefore, the branch parameter
+ will be unique across all transactions sent by that client. The
+ request matches a transaction if:
+
+ 1. the branch parameter in the request is equal to the one in the
+ top Via header field of the request that created the
+ transaction, and
+
+ 2. the sent-by value in the top Via of the request is equal to the
+ one in the request that created the transaction, and
+
+ 3. the method of the request matches the one that created the
+ transaction, except for ACK, where the method of the request
+ that created the transaction is INVITE.
+ */
+ tsip_transac_t *ret = tsk_null;
+ tsip_transac_t *transac;
+ tsk_list_item_t *item;
+ //const char* sent_by;
+
+ /* Check first Via/CSeq validity */
+ if(!message->firstVia || !message->CSeq) {
+ return tsk_null;
+ }
+
+ tsk_safeobj_lock(self);
+
+ tsk_list_foreach(item, self->transactions) {
+ transac = item->data;
+ if(TSIP_REQUEST_IS_ACK(message) && tsk_strequals(transac->callid, message->Call_ID->value)) { /* 1. ACK branch won't match INVITE's but they MUST have the same CSeq/CallId values */
+ // [transac->type == tsip_transac_type_ist] is used to avoid looping in webrtc2sip mode (e.g. browser <->(breaker)<->browser)
+ // (browser-1) -> INVITE -> (breaker) -> INVITE - (server) -> INVITE -> (breaker) -> (browser-2)
+ // the breaker will have two transactions (IST and ICT) with same cseq value and call-id (if not changed by the server)
+ if(transac->type == tsip_transac_type_ist && tsk_striequals(transac->cseq_method, "INVITE") && message->CSeq->seq == transac->cseq_value) {
+ ret = tsk_object_ref(transac);
+ break;
+ }
+ }
+ else if(tsk_strequals(transac->branch, message->firstVia->branch) /* 2. Compare branches*/
+ && (1 == 1) /* FIXME: compare host:ip */
+ ) {
+ if(tsk_strequals(transac->cseq_method, message->CSeq->method)) {
+ ret = tsk_object_ref(transac);
+ break;
+ }
+ else if(TSIP_REQUEST_IS_CANCEL(message) || TSIP_RESPONSE_IS_TO_CANCEL(message)) {
+ ret = tsk_object_ref(transac);
+ break;
+ }
+ }
+ }
+
+ tsk_safeobj_unlock(self);
+
+ return ret;
}
@@ -272,31 +267,31 @@ tsip_transac_t* tsip_transac_layer_find_server(const tsip_transac_layer_t *self,
**/
int tsip_transac_layer_handle_incoming_msg(const tsip_transac_layer_t *self, const tsip_message_t* message)
{
- int ret = -1;
- tsip_transac_t *transac = tsk_null;
-
- if(!message){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
-
- //tsk_safeobj_lock(self);
-
- if(TSIP_MESSAGE_IS_REQUEST(message)){
- transac = tsip_transac_layer_find_server(self, /*TSIP_MESSAGE_AS_REQUEST*/(message));
- }
- else{
- transac = tsip_transac_layer_find_client(self, /*TSIP_MESSAGE_AS_RESPONSE*/(message));
- }
-
- //tsk_safeobj_unlock(self);
-
- if(transac){
- ret = transac->callback(transac, tsip_transac_incoming_msg, message);
- tsk_object_unref(transac);
- }
-
- return ret;
+ int ret = -1;
+ tsip_transac_t *transac = tsk_null;
+
+ if(!message) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+
+ //tsk_safeobj_lock(self);
+
+ if(TSIP_MESSAGE_IS_REQUEST(message)) {
+ transac = tsip_transac_layer_find_server(self, /*TSIP_MESSAGE_AS_REQUEST*/(message));
+ }
+ else {
+ transac = tsip_transac_layer_find_client(self, /*TSIP_MESSAGE_AS_RESPONSE*/(message));
+ }
+
+ //tsk_safeobj_unlock(self);
+
+ if(transac) {
+ ret = transac->callback(transac, tsip_transac_incoming_msg, message);
+ tsk_object_unref(transac);
+ }
+
+ return ret;
}
@@ -314,39 +309,38 @@ int tsip_transac_layer_handle_incoming_msg(const tsip_transac_layer_t *self, con
//
static tsk_object_t* tsip_transac_layer_ctor(tsk_object_t * self, va_list * app)
{
- tsip_transac_layer_t *layer = self;
- if(layer){
- layer->stack = va_arg(*app, const tsip_stack_handle_t *);
- layer->transactions = tsk_list_create();
-
- tsk_safeobj_init(layer);
- }
- return self;
+ tsip_transac_layer_t *layer = self;
+ if(layer) {
+ layer->stack = va_arg(*app, const tsip_stack_handle_t *);
+ layer->transactions = tsk_list_create();
+
+ tsk_safeobj_init(layer);
+ }
+ return self;
}
static tsk_object_t* tsip_transac_layer_dtor(tsk_object_t * self)
-{
- tsip_transac_layer_t *layer = self;
- if(layer){
- TSK_OBJECT_SAFE_FREE(layer->transactions);
+{
+ tsip_transac_layer_t *layer = self;
+ if(layer) {
+ TSK_OBJECT_SAFE_FREE(layer->transactions);
- tsk_safeobj_deinit(layer);
+ tsk_safeobj_deinit(layer);
- TSK_DEBUG_INFO("*** Transaction Layer destroyed ***");
- }
- return self;
+ TSK_DEBUG_INFO("*** Transaction Layer destroyed ***");
+ }
+ return self;
}
static int tsip_transac_layer_cmp(const tsk_object_t *obj1, const tsk_object_t *obj2)
{
- return -1;
+ return -1;
}
-static const tsk_object_def_t tsip_transac_layer_def_s =
-{
- sizeof(tsip_transac_layer_t),
- tsip_transac_layer_ctor,
- tsip_transac_layer_dtor,
- tsip_transac_layer_cmp,
+static const tsk_object_def_t tsip_transac_layer_def_s = {
+ sizeof(tsip_transac_layer_t),
+ tsip_transac_layer_ctor,
+ tsip_transac_layer_dtor,
+ tsip_transac_layer_cmp,
};
const tsk_object_def_t *tsip_transac_layer_def_t = &tsip_transac_layer_def_s;
diff --git a/tinySIP/src/transactions/tsip_transac_nict.c b/tinySIP/src/transactions/tsip_transac_nict.c
index c16e503..cdae368 100755
--- a/tinySIP/src/transactions/tsip_transac_nict.c
+++ b/tinySIP/src/transactions/tsip_transac_nict.c
@@ -2,19 +2,19 @@
* Copyright (C) 2010-2011 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -102,29 +102,27 @@ static int tsip_transac_nict_Any_2_Terminated_X_cancel(va_list *app); /* doubang
/* ======================== conds ======================== */
/* ======================== actions ======================== */
-typedef enum _fsm_action_e
-{
- _fsm_action_cancel = tsip_atype_cancel,
-
- _fsm_action_send = 0xFF,
- _fsm_action_timerE,
- _fsm_action_timerF,
- _fsm_action_timerK,
- _fsm_action_1xx,
- _fsm_action_200_to_699,
- _fsm_action_transporterror,
- _fsm_action_error,
+typedef enum _fsm_action_e {
+ _fsm_action_cancel = tsip_atype_cancel,
+
+ _fsm_action_send = 0xFF,
+ _fsm_action_timerE,
+ _fsm_action_timerF,
+ _fsm_action_timerK,
+ _fsm_action_1xx,
+ _fsm_action_200_to_699,
+ _fsm_action_transporterror,
+ _fsm_action_error,
}
_fsm_action_t;
/* ======================== states ======================== */
-typedef enum _fsm_state_e
-{
- _fsm_state_Started,
- _fsm_state_Trying,
- _fsm_state_Proceeding,
- _fsm_state_Completed,
- _fsm_state_Terminated
+typedef enum _fsm_state_e {
+ _fsm_state_Started,
+ _fsm_state_Trying,
+ _fsm_state_Proceeding,
+ _fsm_state_Completed,
+ _fsm_state_Terminated
}
_fsm_state_t;
@@ -133,74 +131,71 @@ _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 NIC transaction.
- * @param type The event type.
+ * @param [in,out] self A pointer to the NIC transaction.
+ * @param type The event type.
* @param [in,out] msg The incoming message.
*
- * @return Zero if succeed and no-zero error code otherwise.
+ * @return Zero if succeed and no-zero error code otherwise.
**/
int tsip_transac_nict_event_callback(const tsip_transac_nict_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 = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_1xx, msg);
- }
- else if(TSIP_RESPONSE_IS_23456(msg)){
- ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_200_to_699, 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 = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_error, msg);
- break;
- }
-
- case tsip_transac_transport_error:
- {
- ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_transporterror, msg);
- break;
- }
-
- default: break;
- }
-
- return ret;
+{
+ int ret = 0;
+
+ switch(type) {
+ case tsip_transac_incoming_msg: {
+ if(msg && TSIP_MESSAGE_IS_RESPONSE(msg)) {
+ if(TSIP_RESPONSE_IS_1XX(msg)) {
+ ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_1xx, msg);
+ }
+ else if(TSIP_RESPONSE_IS_23456(msg)) {
+ ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_200_to_699, 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 = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_error, msg);
+ break;
+ }
+
+ case tsip_transac_transport_error: {
+ ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_transporterror, msg);
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ return ret;
}
int tsip_transac_nict_timer_callback(const tsip_transac_nict_t* self, tsk_timer_id_t timer_id)
{
- int ret = -1;
-
- if(self){
- if(timer_id == self->timerE.id){
- ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_timerE, tsk_null);
- }
- else if(timer_id == self->timerF.id){
- ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_timerF, tsk_null);
- }
- else if(timer_id == self->timerK.id){
- ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_timerK, tsk_null);
- }
- }
-
- return ret;
+ int ret = -1;
+
+ if(self) {
+ if(timer_id == self->timerE.id) {
+ ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_timerE, tsk_null);
+ }
+ else if(timer_id == self->timerF.id) {
+ ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_timerF, tsk_null);
+ }
+ else if(timer_id == self->timerK.id) {
+ ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_timerK, tsk_null);
+ }
+ }
+
+ return ret;
}
/** Initializes the transaction.
@@ -212,126 +207,126 @@ int tsip_transac_nict_timer_callback(const tsip_transac_nict_t* self, tsk_timer_
**/
int tsip_transac_nict_init(tsip_transac_nict_t *self)
{
- /* Initialize the state machine. */
- tsk_fsm_set(TSIP_TRANSAC_GET_FSM(self),
-
- /*=======================
- * === Started ===
- */
- // Started -> (Send) -> Trying
- 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 ===
- */
- // Trying -> (timerE) -> Trying
- TSK_FSM_ADD_ALWAYS(_fsm_state_Trying, _fsm_action_timerE, _fsm_state_Trying, tsip_transac_nict_Trying_2_Trying_X_timerE, "tsip_transac_nict_Trying_2_Trying_X_timerE"),
- // Trying -> (timerF) -> Terminated
- TSK_FSM_ADD_ALWAYS(_fsm_state_Trying, _fsm_action_timerF, _fsm_state_Terminated, tsip_transac_nict_Trying_2_Terminated_X_timerF, "tsip_transac_nict_Trying_2_Terminated_X_timerF"),
- // Trying -> (transport error) -> Terminated
- TSK_FSM_ADD_ALWAYS(_fsm_state_Trying, _fsm_action_transporterror, _fsm_state_Terminated, tsip_transac_nict_Trying_2_Terminated_X_transportError, "tsip_transac_nict_Trying_2_Terminated_X_transportError"),
- // Trying -> (1xx) -> Proceeding
- 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 ===
- */
- // Proceeding -> (timerE) -> Proceeding
- TSK_FSM_ADD_ALWAYS(_fsm_state_Proceeding, _fsm_action_timerE, _fsm_state_Proceeding, tsip_transac_nict_Proceeding_2_Proceeding_X_timerE, "tsip_transac_nict_Proceeding_2_Proceeding_X_timerE"),
- // Proceeding -> (timerF) -> Terminated
- TSK_FSM_ADD_ALWAYS(_fsm_state_Proceeding, _fsm_action_timerF, _fsm_state_Terminated, tsip_transac_nict_Proceeding_2_Terminated_X_timerF, "tsip_transac_nict_Proceeding_2_Terminated_X_timerF"),
- // Proceeding -> (transport error) -> Terminated
- TSK_FSM_ADD_ALWAYS(_fsm_state_Proceeding, _fsm_action_transporterror, _fsm_state_Terminated, tsip_transac_nict_Proceeding_2_Terminated_X_transportError, "tsip_transac_nict_Proceeding_2_Terminated_X_transportError"),
- // Proceeding -> (1xx) -> Proceeding
- 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 ===
- */
- // 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 ===
- */
- // Any -> (transport error) -> Terminated
- TSK_FSM_ADD_ALWAYS(tsk_fsm_state_any, _fsm_action_transporterror, _fsm_state_Terminated, tsip_transac_nict_Any_2_Terminated_X_transportError, "tsip_transac_nict_Any_2_Terminated_X_transportError"),
- // Any -> (error) -> Terminated
- TSK_FSM_ADD_ALWAYS(tsk_fsm_state_any, _fsm_action_error, _fsm_state_Terminated, tsip_transac_nict_Any_2_Terminated_X_Error, "tsip_transac_nict_Any_2_Terminated_X_Error"),
- // Any -> (cancel) -> Terminated
- TSK_FSM_ADD_ALWAYS(tsk_fsm_state_any, _fsm_action_cancel, _fsm_state_Terminated, tsip_transac_nict_Any_2_Terminated_X_cancel, "tsip_transac_nict_Any_2_Terminated_X_cancel"),
-
- 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_F(tsip_transac_nict_event_callback);
-
- /* 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);
-
- return 0;
+ /* Initialize the state machine. */
+ tsk_fsm_set(TSIP_TRANSAC_GET_FSM(self),
+
+ /*=======================
+ * === Started ===
+ */
+ // Started -> (Send) -> Trying
+ 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 ===
+ */
+ // Trying -> (timerE) -> Trying
+ TSK_FSM_ADD_ALWAYS(_fsm_state_Trying, _fsm_action_timerE, _fsm_state_Trying, tsip_transac_nict_Trying_2_Trying_X_timerE, "tsip_transac_nict_Trying_2_Trying_X_timerE"),
+ // Trying -> (timerF) -> Terminated
+ TSK_FSM_ADD_ALWAYS(_fsm_state_Trying, _fsm_action_timerF, _fsm_state_Terminated, tsip_transac_nict_Trying_2_Terminated_X_timerF, "tsip_transac_nict_Trying_2_Terminated_X_timerF"),
+ // Trying -> (transport error) -> Terminated
+ TSK_FSM_ADD_ALWAYS(_fsm_state_Trying, _fsm_action_transporterror, _fsm_state_Terminated, tsip_transac_nict_Trying_2_Terminated_X_transportError, "tsip_transac_nict_Trying_2_Terminated_X_transportError"),
+ // Trying -> (1xx) -> Proceeding
+ 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 ===
+ */
+ // Proceeding -> (timerE) -> Proceeding
+ TSK_FSM_ADD_ALWAYS(_fsm_state_Proceeding, _fsm_action_timerE, _fsm_state_Proceeding, tsip_transac_nict_Proceeding_2_Proceeding_X_timerE, "tsip_transac_nict_Proceeding_2_Proceeding_X_timerE"),
+ // Proceeding -> (timerF) -> Terminated
+ TSK_FSM_ADD_ALWAYS(_fsm_state_Proceeding, _fsm_action_timerF, _fsm_state_Terminated, tsip_transac_nict_Proceeding_2_Terminated_X_timerF, "tsip_transac_nict_Proceeding_2_Terminated_X_timerF"),
+ // Proceeding -> (transport error) -> Terminated
+ TSK_FSM_ADD_ALWAYS(_fsm_state_Proceeding, _fsm_action_transporterror, _fsm_state_Terminated, tsip_transac_nict_Proceeding_2_Terminated_X_transportError, "tsip_transac_nict_Proceeding_2_Terminated_X_transportError"),
+ // Proceeding -> (1xx) -> Proceeding
+ 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 ===
+ */
+ // 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 ===
+ */
+ // Any -> (transport error) -> Terminated
+ TSK_FSM_ADD_ALWAYS(tsk_fsm_state_any, _fsm_action_transporterror, _fsm_state_Terminated, tsip_transac_nict_Any_2_Terminated_X_transportError, "tsip_transac_nict_Any_2_Terminated_X_transportError"),
+ // Any -> (error) -> Terminated
+ TSK_FSM_ADD_ALWAYS(tsk_fsm_state_any, _fsm_action_error, _fsm_state_Terminated, tsip_transac_nict_Any_2_Terminated_X_Error, "tsip_transac_nict_Any_2_Terminated_X_Error"),
+ // Any -> (cancel) -> Terminated
+ TSK_FSM_ADD_ALWAYS(tsk_fsm_state_any, _fsm_action_cancel, _fsm_state_Terminated, tsip_transac_nict_Any_2_Terminated_X_cancel, "tsip_transac_nict_Any_2_Terminated_X_cancel"),
+
+ 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_F(tsip_transac_nict_event_callback);
+
+ /* 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);
+
+ return 0;
}
tsip_transac_nict_t* tsip_transac_nict_create(int32_t cseq_value, const char* cseq_method, const char* callid, tsip_transac_dst_t* dst)
{
- tsip_transac_nict_t* transac = tsk_object_new(tsip_transac_nict_def_t);
- if(transac){
- // initialize base class
- tsip_transac_init(TSIP_TRANSAC(transac), tsip_transac_type_nict, cseq_value, cseq_method, callid, dst, _fsm_state_Started, _fsm_state_Terminated);
-
- // init FSM
- TSIP_TRANSAC_GET_FSM(transac)->debug = DEBUG_STATE_MACHINE;
- tsk_fsm_set_callback_terminated(TSIP_TRANSAC_GET_FSM(transac), TSK_FSM_ONTERMINATED_F(tsip_transac_nict_OnTerminated), (const void*)transac);
-
- // initialize NICT object
- tsip_transac_nict_init(transac);
- }
- return transac;
+ tsip_transac_nict_t* transac = tsk_object_new(tsip_transac_nict_def_t);
+ if(transac) {
+ // initialize base class
+ tsip_transac_init(TSIP_TRANSAC(transac), tsip_transac_type_nict, cseq_value, cseq_method, callid, dst, _fsm_state_Started, _fsm_state_Terminated);
+
+ // init FSM
+ TSIP_TRANSAC_GET_FSM(transac)->debug = DEBUG_STATE_MACHINE;
+ tsk_fsm_set_callback_terminated(TSIP_TRANSAC_GET_FSM(transac), TSK_FSM_ONTERMINATED_F(tsip_transac_nict_OnTerminated), (const void*)transac);
+
+ // initialize NICT object
+ tsip_transac_nict_init(transac);
+ }
+ return transac;
}
/**
* Starts the client transaction.
*
- * @param [in,out] self The client transaction to start.
- * @param [in,out] request The SIP/IMS request to send.
+ * @param [in,out] self The client transaction to start.
+ * @param [in,out] request The SIP/IMS request to send.
*
- * @return Zero if succeed and non-zero error code otherwise.
+ * @return Zero if succeed and non-zero error code otherwise.
**/
int tsip_transac_nict_start(tsip_transac_nict_t *self, const tsip_request_t* request)
{
- int ret = -1;
- if(self && request && !TSIP_TRANSAC(self)->running){
- /* Add branch to the new client transaction
- * - CANCEL will have the same Via and Contact headers as the request it cancel
- * - Transac will use request branch if exit (e.g. when request received over websocket)
- */
- if((request->firstVia && !tsk_strnullORempty(request->firstVia->branch))){
- tsk_strupdate(&TSIP_TRANSAC(self)->branch, (request->firstVia ? request->firstVia->branch : "doubango"));
- }
- else if((TSIP_TRANSAC(self)->branch = tsk_strdup(TSIP_TRANSAC_MAGIC_COOKIE))){
- tsk_istr_t branch;
- tsk_strrandom(&branch);
- tsk_strcat_2(&(TSIP_TRANSAC(self)->branch), "-%s", branch);
- }
-
- TSIP_TRANSAC(self)->running = tsk_true;
- self->request = tsk_object_ref((void*)request);
-
- ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_send, tsk_null);
- }
- return ret;
+ int ret = -1;
+ if(self && request && !TSIP_TRANSAC(self)->running) {
+ /* Add branch to the new client transaction
+ * - CANCEL will have the same Via and Contact headers as the request it cancel
+ * - Transac will use request branch if exit (e.g. when request received over websocket)
+ */
+ if((request->firstVia && !tsk_strnullORempty(request->firstVia->branch))) {
+ tsk_strupdate(&TSIP_TRANSAC(self)->branch, (request->firstVia ? request->firstVia->branch : "doubango"));
+ }
+ else if((TSIP_TRANSAC(self)->branch = tsk_strdup(TSIP_TRANSAC_MAGIC_COOKIE))) {
+ tsk_istr_t branch;
+ tsk_strrandom(&branch);
+ tsk_strcat_2(&(TSIP_TRANSAC(self)->branch), "-%s", branch);
+ }
+
+ TSIP_TRANSAC(self)->running = tsk_true;
+ self->request = tsk_object_ref((void*)request);
+
+ ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_send, tsk_null);
+ }
+ return ret;
}
@@ -350,304 +345,304 @@ 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 *);
-
- //== Send the request
- tsip_transac_send(TSIP_TRANSAC(self), TSIP_TRANSAC(self)->branch, TSIP_MESSAGE(self->request));
-
- // Now that the first request is sent using the best transport mean we know if it's reliable or not
- if(TNET_SOCKET_TYPE_IS_VALID(self->request->dst_net_type)){
- TSIP_TRANSAC(self)->reliable = TNET_SOCKET_TYPE_IS_STREAM(self->request->dst_net_type);
- self->timerK.timeout = TSIP_TRANSAC(self)->reliable ? 0 : TSIP_TIMER_GET(K); /* RFC 3261 - 17.1.2.2*/
- }
-
- /* RFC 3261 - 17.1.2.2
- The "Trying" state is entered when the TU initiates a new client
- transaction with a request. When entering this state, the client
- transaction SHOULD set timer F to fire in 64*T1 seconds.
- */
- TRANSAC_NICT_TIMER_SCHEDULE(F);
-
- /* RFC 3261 - 17.1.2.2
- If an unreliable transport is in use, the client transaction MUST set timer
- E to fire in T1 seconds.
- */
- if(!TSIP_TRANSAC(self)->reliable){
- TRANSAC_NICT_TIMER_SCHEDULE(E);
- }
-
- return 0;
+ tsip_transac_nict_t *self = va_arg(*app, tsip_transac_nict_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));
+
+ // Now that the first request is sent using the best transport mean we know if it's reliable or not
+ if(TNET_SOCKET_TYPE_IS_VALID(self->request->dst_net_type)) {
+ TSIP_TRANSAC(self)->reliable = TNET_SOCKET_TYPE_IS_STREAM(self->request->dst_net_type);
+ self->timerK.timeout = TSIP_TRANSAC(self)->reliable ? 0 : TSIP_TIMER_GET(K); /* RFC 3261 - 17.1.2.2*/
+ }
+
+ /* RFC 3261 - 17.1.2.2
+ The "Trying" state is entered when the TU initiates a new client
+ transaction with a request. When entering this state, the client
+ transaction SHOULD set timer F to fire in 64*T1 seconds.
+ */
+ TRANSAC_NICT_TIMER_SCHEDULE(F);
+
+ /* RFC 3261 - 17.1.2.2
+ If an unreliable transport is in use, the client transaction MUST set timer
+ E to fire in T1 seconds.
+ */
+ if(!TSIP_TRANSAC(self)->reliable) {
+ TRANSAC_NICT_TIMER_SCHEDULE(E);
+ }
+
+ return 0;
}
/* Trying -> (Timer E) -> Trying
*/
int tsip_transac_nict_Trying_2_Trying_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 *);*/
-
- //== Send the request
- tsip_transac_send(TSIP_TRANSAC(self), TSIP_TRANSAC(self)->branch, self->request);
-
- /* RFC 3261 - 17.1.2.2
- If timer E fires while still in this (Trying) state, the timer is reset, but this time with a value of MIN(2*T1, T2).
- When the timer fires again, it is reset to a MIN(4*T1, T2). This process continues so that retransmissions occur with an exponentially
- increasing interval that caps at T2. The default value of T2 is 4s, and it represents the amount of time a non-INVITE server transaction
- will take to respond to a request, if it does not respond immediately. For the default values of T1 and T2, this results in
- intervals of 500 ms, 1 s, 2 s, 4 s, 4 s, 4 s, etc.
- */
- self->timerE.timeout = TSK_MIN((self->timerE.timeout<<1), TSIP_TIMER_GET(T2));
- TRANSAC_NICT_TIMER_SCHEDULE(E);
-
- return 0;
+ tsip_transac_nict_t *self = va_arg(*app, tsip_transac_nict_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);
+
+ /* RFC 3261 - 17.1.2.2
+ If timer E fires while still in this (Trying) state, the timer is reset, but this time with a value of MIN(2*T1, T2).
+ When the timer fires again, it is reset to a MIN(4*T1, T2). This process continues so that retransmissions occur with an exponentially
+ increasing interval that caps at T2. The default value of T2 is 4s, and it represents the amount of time a non-INVITE server transaction
+ will take to respond to a request, if it does not respond immediately. For the default values of T1 and T2, this results in
+ intervals of 500 ms, 1 s, 2 s, 4 s, 4 s, 4 s, etc.
+ */
+ self->timerE.timeout = TSK_MIN((self->timerE.timeout<<1), TSIP_TIMER_GET(T2));
+ TRANSAC_NICT_TIMER_SCHEDULE(E);
+
+ return 0;
}
/* Trying -> (Timer F) -> Terminated
*/
int tsip_transac_nict_Trying_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 *);*/
+ 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 F fires while the client transaction is still in the
- "Trying" state, the client transaction SHOULD inform the TU about the
- timeout, and then it SHOULD enter the "Terminated" state.
- */
+ /* RFC 3261 - 17.1.2.2
+ If Timer F fires while the client transaction is still in the
+ "Trying" state, the client transaction SHOULD inform the TU about the
+ timeout, and then it SHOULD enter the "Terminated" state.
+ */
- /* Timers will be canceled by "tsip_transac_nict_OnTerminated" */
-
- tsip_transac_deliver(TSIP_TRANSAC(self), tsip_dialog_timedout, self->request);
+ /* Timers will be canceled by "tsip_transac_nict_OnTerminated" */
- return 0;
+ tsip_transac_deliver(TSIP_TRANSAC(self), tsip_dialog_timedout, self->request);
+
+ return 0;
}
/* Trying -> (Transport Error) -> Terminated
*/
int tsip_transac_nict_Trying_2_Terminated_X_transportError(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 *);*/
- /* Timers will be canceled by "tsip_transac_nict_OnTerminated" */
+ /* Timers will be canceled by "tsip_transac_nict_OnTerminated" */
- tsip_transac_deliver(TSIP_TRANSAC(self), tsip_dialog_transport_error, self->request);
+ tsip_transac_deliver(TSIP_TRANSAC(self), tsip_dialog_transport_error, self->request);
- return 0;
+ return 0;
}
/* Trying -> (1xx) -> Proceeding
*/
int tsip_transac_nict_Trying_2_Proceedding_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 *);
-
- /* RFC 3261 - 17.1.2.2
- If a provisional response is received while in the "Trying" state, the
- response MUST be passed to the TU, and then the client transaction
- SHOULD move to the "Proceeding" state.
- */
-
- /* Cancel timers */
- if(!TSIP_TRANSAC(self)->reliable){
- TRANSAC_TIMER_CANCEL(E);
- }
- TRANSAC_TIMER_CANCEL(F); /* Now it's up to the UAS to update the FSM. */
-
- /* Pass the provisional response to the dialog. */
- tsip_transac_deliver(TSIP_TRANSAC(self), tsip_dialog_i_msg, message);
-
- return 0;
+ 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 a provisional response is received while in the "Trying" state, the
+ response MUST be passed to the TU, and then the client transaction
+ SHOULD move to the "Proceeding" state.
+ */
+
+ /* Cancel timers */
+ if(!TSIP_TRANSAC(self)->reliable) {
+ TRANSAC_TIMER_CANCEL(E);
+ }
+ TRANSAC_TIMER_CANCEL(F); /* Now it's up to the UAS to update the FSM. */
+
+ /* Pass the provisional response to the dialog. */
+ tsip_transac_deliver(TSIP_TRANSAC(self), tsip_dialog_i_msg, message);
+
+ return 0;
}
/* Trying -> (200-699) -> Completed
*/
int tsip_transac_nict_Trying_2_Completed_X_200_to_699(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 a final response (status codes 200-699) is received while in the "Trying" state, the response
- MUST be passed to the TU, and the client transaction MUST transition
- to the "Completed" state.
+ /* RFC 3261 - 17.1.2.2
+ If a final response (status codes 200-699) is received while in the "Trying" state, the response
+ MUST be passed to the TU, and the client transaction MUST transition
+ to the "Completed" state.
- If Timer K fires while in this state (Completed), the client transaction MUST transition to the "Terminated" state.
- */
+ If Timer K fires while in this state (Completed), the client transaction MUST transition to the "Terminated" state.
+ */
- if(!TSIP_TRANSAC(self)->reliable){
- TRANSAC_TIMER_CANCEL(E);
- }
- TRANSAC_TIMER_CANCEL(F);
+ if(!TSIP_TRANSAC(self)->reliable) {
+ TRANSAC_TIMER_CANCEL(E);
+ }
+ TRANSAC_TIMER_CANCEL(F);
- tsip_transac_deliver(TSIP_TRANSAC(self), tsip_dialog_i_msg, message);
+ tsip_transac_deliver(TSIP_TRANSAC(self), tsip_dialog_i_msg, message);
- /* SCHEDULE timer K */
- TRANSAC_NICT_TIMER_SCHEDULE(K);
+ /* SCHEDULE timer K */
+ TRANSAC_NICT_TIMER_SCHEDULE(K);
- return 0;
+ return 0;
}
/* Proceeding -> (TimerE) -> Proceeding
*/
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 *);
+ tsip_transac_nict_t *self = va_arg(*app, tsip_transac_nict_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);
+ //== Send the request
+ tsip_transac_send(TSIP_TRANSAC(self), TSIP_TRANSAC(self)->branch, self->request);
- /* RFC 3261 - 17.1.2.2
- If Timer E fires while in the "Proceeding" state, the request MUST be
- passed to the transport layer for retransmission, and Timer E MUST be
- reset with a value of T2 seconds.
- */
- self->timerE.timeout = TSK_MIN(self->timerE.timeout*2, TSIP_TIMER_GET(T2));
- TRANSAC_NICT_TIMER_SCHEDULE(E);
+ /* RFC 3261 - 17.1.2.2
+ If Timer E fires while in the "Proceeding" state, the request MUST be
+ passed to the transport layer for retransmission, and Timer E MUST be
+ reset with a value of T2 seconds.
+ */
+ self->timerE.timeout = TSK_MIN(self->timerE.timeout*2, TSIP_TIMER_GET(T2));
+ TRANSAC_NICT_TIMER_SCHEDULE(E);
- return 0;
+ return 0;
}
/* Proceeding -> (Timer F) -> Proceeding
*/
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 *);
+ 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 F fires while in the "Proceeding" state, the TU MUST be informed of a timeout, and the
- client transaction MUST transition to the terminated state.
- */
+ /* 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
+ client transaction MUST transition to the terminated state.
+ */
- /* Timers will be canceled by "tsip_transac_nict_OnTerminated" */
+ /* Timers will be canceled by "tsip_transac_nict_OnTerminated" */
- tsip_transac_deliver(TSIP_TRANSAC(self), tsip_dialog_transport_error, tsk_null);
+ tsip_transac_deliver(TSIP_TRANSAC(self), tsip_dialog_transport_error, tsk_null);
- return 0;
+ return 0;
}
/* Proceeding -> (Transport error) -> Terminated
*/
int tsip_transac_nict_Proceeding_2_Terminated_X_transportError(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 *);*/
- /* Timers will be canceles by On */
- tsip_transac_deliver(TSIP_TRANSAC(self), tsip_dialog_transport_error, 0);
+ /* Timers will be canceles by On */
+ tsip_transac_deliver(TSIP_TRANSAC(self), tsip_dialog_transport_error, 0);
- return 0;
+ return 0;
}
/* Proceeding -> (1xx) -> Proceeding
*/
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 *);
+ 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){
- TRANSAC_TIMER_CANCEL(E);
- }
- tsip_transac_deliver(TSIP_TRANSAC(self), tsip_dialog_i_msg, message);
+ if(!TSIP_TRANSAC(self)->reliable) {
+ TRANSAC_TIMER_CANCEL(E);
+ }
+ tsip_transac_deliver(TSIP_TRANSAC(self), tsip_dialog_i_msg, message);
- return 0;
+ return 0;
}
/* Proceeding -> (200-699) -> Completed
*/
int tsip_transac_nict_Proceeding_2_Completed_X_200_to_699(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 *);
-
- /* RFC 3261 - 17.1.2.2
- If a final response (status codes 200-699) is received while in the
- "Proceeding" state, the response MUST be passed to the TU, and the
- client transaction MUST transition to the "Completed" state.
- */
-
- /* RFC 3261 - 17.1.2.2
- Once the client transaction enters the "Completed" state, it MUST set
- Timer K to fire in T4 seconds for unreliable transports, and zero
- seconds for reliable transports. The "Completed" state exists to
- buffer any additional response retransmissions that may be received
- (which is why the client transaction remains there only for
-
- unreliable transports). T4 represents the amount of time the network
- will take to clear messages between client and server transactions.
- The default value of T4 is 5s.
- */
-
- if(!TSIP_TRANSAC(self)->reliable){
- TRANSAC_TIMER_CANCEL(E);
- }
-
- tsip_transac_deliver(TSIP_TRANSAC(self), tsip_dialog_i_msg, message);
-
- /* SCHEDULE timer K */
- TRANSAC_NICT_TIMER_SCHEDULE(K);
-
- return 0;
+ 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 a final response (status codes 200-699) is received while in the
+ "Proceeding" state, the response MUST be passed to the TU, and the
+ client transaction MUST transition to the "Completed" state.
+ */
+
+ /* RFC 3261 - 17.1.2.2
+ Once the client transaction enters the "Completed" state, it MUST set
+ Timer K to fire in T4 seconds for unreliable transports, and zero
+ seconds for reliable transports. The "Completed" state exists to
+ buffer any additional response retransmissions that may be received
+ (which is why the client transaction remains there only for
+
+ unreliable transports). T4 represents the amount of time the network
+ will take to clear messages between client and server transactions.
+ The default value of T4 is 5s.
+ */
+
+ if(!TSIP_TRANSAC(self)->reliable) {
+ TRANSAC_TIMER_CANCEL(E);
+ }
+
+ tsip_transac_deliver(TSIP_TRANSAC(self), tsip_dialog_i_msg, message);
+
+ /* SCHEDULE timer K */
+ TRANSAC_NICT_TIMER_SCHEDULE(K);
+
+ return 0;
}
/* Completed -> (Timer K) -> Terminated
*/
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
+ MUST transition to the "Terminated" state.
+ */
- /* RFC 3261 - 17.1.2.2
- If Timer K fires while in this state (Completed), the client transaction
- MUST transition to the "Terminated" state.
- */
-
- /* RFC 3261 - 17.1.2.2
- ONCE THE TRANSACTION IS IN THE TERMINATED STATE, IT MUST BE DESTROYED IMMEDIATELY.
- */
+ /* RFC 3261 - 17.1.2.2
+ ONCE THE TRANSACTION IS IN THE TERMINATED STATE, IT MUST BE DESTROYED IMMEDIATELY.
+ */
- /* Timers will be canceled by "tsip_transac_nict_OnTerminated" */
+ /* Timers will be canceled by "tsip_transac_nict_OnTerminated" */
- //tsip_transac_deliver(TSIP_TRANSAC(self), tsip_dialog_transac_ok, 0);
+ //tsip_transac_deliver(TSIP_TRANSAC(self), tsip_dialog_transac_ok, 0);
- return 0;
+ return 0;
}
/* Any -> (Transport Error) -> Terminated
*/
int tsip_transac_nict_Any_2_Terminated_X_transportError(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 *);
- /* Timers will be canceled by "tsip_transac_nict_OnTerminated" */
+ /* Timers will be canceled by "tsip_transac_nict_OnTerminated" */
- return tsip_transac_deliver(TSIP_TRANSAC(self), tsip_dialog_transport_error, tsk_null);
+ return tsip_transac_deliver(TSIP_TRANSAC(self), tsip_dialog_transport_error, tsk_null);
}
/* Any -> (Error) -> Terminated
*/
int tsip_transac_nict_Any_2_Terminated_X_Error(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 *);
- /* Timers will be canceled by "tsip_transac_nict_OnTerminated" */
+ /* Timers will be canceled by "tsip_transac_nict_OnTerminated" */
- return tsip_transac_deliver(TSIP_TRANSAC(self), tsip_dialog_error, tsk_null);
+ return tsip_transac_deliver(TSIP_TRANSAC(self), tsip_dialog_error, tsk_null);
}
/* Any -> (cancel) -> Terminated
*/
int tsip_transac_nict_Any_2_Terminated_X_cancel(va_list *app)
{
- /* doubango-specific */
- return 0;
+ /* doubango-specific */
+ return 0;
}
@@ -662,10 +657,10 @@ int tsip_transac_nict_Any_2_Terminated_X_cancel(va_list *app)
*/
int tsip_transac_nict_OnTerminated(tsip_transac_nict_t *self)
{
- TSK_DEBUG_INFO("=== NICT terminated ===");
-
- /* Remove (and destroy) the transaction from the layer. */
- return tsip_transac_remove(TSIP_TRANSAC(self));
+ TSK_DEBUG_INFO("=== NICT terminated ===");
+
+ /* Remove (and destroy) the transaction from the layer. */
+ return tsip_transac_remove(TSIP_TRANSAC(self));
}
@@ -688,44 +683,43 @@ int tsip_transac_nict_OnTerminated(tsip_transac_nict_t *self)
//
static tsk_object_t* tsip_transac_nict_ctor(tsk_object_t * self, va_list * app)
{
- tsip_transac_nict_t *transac = self;
- if(transac){
- }
- return self;
+ tsip_transac_nict_t *transac = self;
+ if(transac) {
+ }
+ return self;
}
static tsk_object_t* tsip_transac_nict_dtor(tsk_object_t * _self)
-{
- tsip_transac_nict_t *self = _self;
- if(self){
- /* Cancel timers */
- if(!TSIP_TRANSAC(self)->reliable){
- TRANSAC_TIMER_CANCEL(E);
- }
- TRANSAC_TIMER_CANCEL(F);
- TRANSAC_TIMER_CANCEL(K);
-
- TSIP_TRANSAC(self)->running = tsk_false;
- TSK_OBJECT_SAFE_FREE(self->request);
-
- /* DeInitialize base class */
- tsip_transac_deinit(TSIP_TRANSAC(self));
-
- TSK_DEBUG_INFO("*** NICT destroyed ***");
- }
- return _self;
+{
+ tsip_transac_nict_t *self = _self;
+ if(self) {
+ /* Cancel timers */
+ if(!TSIP_TRANSAC(self)->reliable) {
+ TRANSAC_TIMER_CANCEL(E);
+ }
+ TRANSAC_TIMER_CANCEL(F);
+ TRANSAC_TIMER_CANCEL(K);
+
+ TSIP_TRANSAC(self)->running = tsk_false;
+ TSK_OBJECT_SAFE_FREE(self->request);
+
+ /* DeInitialize base class */
+ tsip_transac_deinit(TSIP_TRANSAC(self));
+
+ TSK_DEBUG_INFO("*** NICT destroyed ***");
+ }
+ return _self;
}
static int tsip_transac_nict_cmp(const tsk_object_t *t1, const tsk_object_t *t2)
{
- return tsip_transac_cmp(t1, t2);
+ return tsip_transac_cmp(t1, t2);
}
-static const tsk_object_def_t tsip_transac_nict_def_s =
-{
- sizeof(tsip_transac_nict_t),
- tsip_transac_nict_ctor,
- tsip_transac_nict_dtor,
- tsip_transac_nict_cmp,
+static const tsk_object_def_t tsip_transac_nict_def_s = {
+ sizeof(tsip_transac_nict_t),
+ tsip_transac_nict_ctor,
+ tsip_transac_nict_dtor,
+ tsip_transac_nict_cmp,
};
const tsk_object_def_t *tsip_transac_nict_def_t = &tsip_transac_nict_def_s;
diff --git a/tinySIP/src/transactions/tsip_transac_nist.c b/tinySIP/src/transactions/tsip_transac_nist.c
index 66424b2..6c99c02 100755
--- a/tinySIP/src/transactions/tsip_transac_nist.c
+++ b/tinySIP/src/transactions/tsip_transac_nist.c
@@ -2,19 +2,19 @@
* Copyright (C) 2010-2011 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -60,7 +60,7 @@
| | |
+-------------->| Terminated|
| |
- +-----------+
+ +-----------+
=============================================================================*/
@@ -104,183 +104,175 @@ int tsip_transac_nist_Any_2_Terminated_X_cancel(va_list *app); /* doubango-speci
/* ======================== conds ======================== */
/* ======================== actions ======================== */
-typedef enum _fsm_action_e
-{
- _fsm_action_cancel = tsip_atype_cancel,
-
- _fsm_action_request = 0xFF,
- _fsm_action_send_1xx,
- _fsm_action_send_200_to_699,
- _fsm_action_timerJ,
- _fsm_action_transporterror,
- _fsm_action_error,
+typedef enum _fsm_action_e {
+ _fsm_action_cancel = tsip_atype_cancel,
+
+ _fsm_action_request = 0xFF,
+ _fsm_action_send_1xx,
+ _fsm_action_send_200_to_699,
+ _fsm_action_timerJ,
+ _fsm_action_transporterror,
+ _fsm_action_error,
}
_fsm_action_t;
/* ======================== states ======================== */
-typedef enum _fsm_state_e
-{
- _fsm_state_Started,
- _fsm_state_Trying,
- _fsm_state_Proceeding,
- _fsm_state_Completed,
- _fsm_state_Terminated
+typedef enum _fsm_state_e {
+ _fsm_state_Started,
+ _fsm_state_Trying,
+ _fsm_state_Proceeding,
+ _fsm_state_Completed,
+ _fsm_state_Terminated
}
_fsm_state_t;
int tsip_transac_nist_event_callback(const tsip_transac_nist_t *self, tsip_transac_event_type_t type, const tsip_message_t *msg)
{
- int ret = -1;
-
- switch(type)
- {
- case tsip_transac_incoming_msg: /* From Transport Layer to Transaction Layer */
- {
- if(msg && TSIP_MESSAGE_IS_REQUEST(msg)){
- ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_request, msg);
- }
- break;
- }
-
- case tsip_transac_outgoing_msg: /* From TU to Transport Layer */
- {
- if(msg && TSIP_MESSAGE_IS_RESPONSE(msg))
- {
- if(TSIP_RESPONSE_IS_1XX(msg)){
- ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_send_1xx, msg);
- }
- else if(TSIP_RESPONSE_IS_23456(msg)){
- ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_send_200_to_699, msg);
- }
- }
- break;
- }
-
- case tsip_transac_canceled:
- case tsip_transac_terminated:
- case tsip_transac_timedout:
- break;
-
- case tsip_transac_error:
- {
- ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_error, msg);
- break;
- }
-
- case tsip_transac_transport_error:
- {
- ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_transporterror, msg);
- break;
- }
- }
-
- return ret;
+ int ret = -1;
+
+ switch(type) {
+ case tsip_transac_incoming_msg: { /* From Transport Layer to Transaction Layer */
+ if(msg && TSIP_MESSAGE_IS_REQUEST(msg)) {
+ ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_request, msg);
+ }
+ break;
+ }
+
+ case tsip_transac_outgoing_msg: { /* From TU to Transport Layer */
+ if(msg && TSIP_MESSAGE_IS_RESPONSE(msg)) {
+ if(TSIP_RESPONSE_IS_1XX(msg)) {
+ ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_send_1xx, msg);
+ }
+ else if(TSIP_RESPONSE_IS_23456(msg)) {
+ ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_send_200_to_699, msg);
+ }
+ }
+ break;
+ }
+
+ case tsip_transac_canceled:
+ case tsip_transac_terminated:
+ case tsip_transac_timedout:
+ break;
+
+ case tsip_transac_error: {
+ ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_error, msg);
+ break;
+ }
+
+ case tsip_transac_transport_error: {
+ ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_transporterror, msg);
+ break;
+ }
+ }
+
+ return ret;
}
int tsip_transac_nist_timer_callback(const tsip_transac_nist_t* self, tsk_timer_id_t timer_id)
{
- int ret = -1;
+ int ret = -1;
- if(self){
- if(timer_id == self->timerJ.id){
- ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_timerJ, tsk_null);
- }
- }
+ if(self) {
+ if(timer_id == self->timerJ.id) {
+ ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_timerJ, tsk_null);
+ }
+ }
- return ret;
+ return ret;
}
int tsip_transac_nist_init(tsip_transac_nist_t *self)
{
- /* Initialize the state machine.
- */
- tsk_fsm_set(TSIP_TRANSAC_GET_FSM(self),
-
- /*=======================
- * === Started ===
- */
- // Started -> (receive request) -> Trying
- 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 other) -> Started
- TSK_FSM_ADD_ALWAYS_NOTHING(_fsm_state_Started, "tsip_transac_nist_Started_2_Started_X_any"),
-
- /*=======================
- * === Trying ===
- */
- // Trying -> (receive request retransmission) -> Trying
- TSK_FSM_ADD_ALWAYS(_fsm_state_Trying, _fsm_action_request, _fsm_state_Trying, tsk_null, "tsip_transac_nist_Trying_2_Trying_X_request"),
- // Trying -> (send 1xx) -> Proceeding
- TSK_FSM_ADD_ALWAYS(_fsm_state_Trying, _fsm_action_send_1xx, _fsm_state_Proceeding, tsip_transac_nist_Trying_2_Proceeding_X_send_1xx, "tsip_transac_nist_Trying_2_Proceeding_X_send_1xx"),
- // 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 ===
- */
- // Proceeding -> (send 1xx) -> Proceeding
- TSK_FSM_ADD_ALWAYS(_fsm_state_Proceeding, _fsm_action_send_1xx, _fsm_state_Proceeding, tsip_transac_nist_Proceeding_2_Proceeding_X_send_1xx, "tsip_transac_nist_Proceeding_2_Proceeding_X_send_1xx"),
- // Proceeding -> (send 200 to 699) -> Completed
- TSK_FSM_ADD_ALWAYS(_fsm_state_Proceeding, _fsm_action_send_200_to_699, _fsm_state_Completed, tsip_transac_nist_Proceeding_2_Completed_X_send_200_to_699, "tsip_transac_nist_Proceeding_2_Completed_X_send_200_to_699"),
- // 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 ===
- */
- // Completed -> (receive request) -> Completed
- 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 ===
- */
- // Any -> (transport error) -> Terminated
- TSK_FSM_ADD_ALWAYS(tsk_fsm_state_any, _fsm_action_transporterror, _fsm_state_Terminated, tsip_transac_nist_Any_2_Terminated_X_transportError, "tsip_transac_nist_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_nist_Any_2_Terminated_X_Error, "tsip_transac_nist_Any_2_Terminated_X_Error"),
- // Any -> (cancel) -> Terminated
- TSK_FSM_ADD_ALWAYS(tsk_fsm_state_any, _fsm_action_cancel, _fsm_state_Terminated, tsip_transac_nist_Any_2_Terminated_X_cancel, "tsip_transac_nist_Any_2_Terminated_X_cancel"),
-
- TSK_FSM_ADD_NULL());
-
- /* Set callback function to call when new messages arrive or errors happen at
- the transport layer.
- */
- TSIP_TRANSAC(self)->callback = TSIP_TRANSAC_EVENT_CALLBACK_F(tsip_transac_nist_event_callback);
-
- return 0;
+ /* Initialize the state machine.
+ */
+ tsk_fsm_set(TSIP_TRANSAC_GET_FSM(self),
+
+ /*=======================
+ * === Started ===
+ */
+ // Started -> (receive request) -> Trying
+ 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 other) -> Started
+ TSK_FSM_ADD_ALWAYS_NOTHING(_fsm_state_Started, "tsip_transac_nist_Started_2_Started_X_any"),
+
+ /*=======================
+ * === Trying ===
+ */
+ // Trying -> (receive request retransmission) -> Trying
+ TSK_FSM_ADD_ALWAYS(_fsm_state_Trying, _fsm_action_request, _fsm_state_Trying, tsk_null, "tsip_transac_nist_Trying_2_Trying_X_request"),
+ // Trying -> (send 1xx) -> Proceeding
+ TSK_FSM_ADD_ALWAYS(_fsm_state_Trying, _fsm_action_send_1xx, _fsm_state_Proceeding, tsip_transac_nist_Trying_2_Proceeding_X_send_1xx, "tsip_transac_nist_Trying_2_Proceeding_X_send_1xx"),
+ // 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 ===
+ */
+ // Proceeding -> (send 1xx) -> Proceeding
+ TSK_FSM_ADD_ALWAYS(_fsm_state_Proceeding, _fsm_action_send_1xx, _fsm_state_Proceeding, tsip_transac_nist_Proceeding_2_Proceeding_X_send_1xx, "tsip_transac_nist_Proceeding_2_Proceeding_X_send_1xx"),
+ // Proceeding -> (send 200 to 699) -> Completed
+ TSK_FSM_ADD_ALWAYS(_fsm_state_Proceeding, _fsm_action_send_200_to_699, _fsm_state_Completed, tsip_transac_nist_Proceeding_2_Completed_X_send_200_to_699, "tsip_transac_nist_Proceeding_2_Completed_X_send_200_to_699"),
+ // 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 ===
+ */
+ // Completed -> (receive request) -> Completed
+ 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 ===
+ */
+ // Any -> (transport error) -> Terminated
+ TSK_FSM_ADD_ALWAYS(tsk_fsm_state_any, _fsm_action_transporterror, _fsm_state_Terminated, tsip_transac_nist_Any_2_Terminated_X_transportError, "tsip_transac_nist_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_nist_Any_2_Terminated_X_Error, "tsip_transac_nist_Any_2_Terminated_X_Error"),
+ // Any -> (cancel) -> Terminated
+ TSK_FSM_ADD_ALWAYS(tsk_fsm_state_any, _fsm_action_cancel, _fsm_state_Terminated, tsip_transac_nist_Any_2_Terminated_X_cancel, "tsip_transac_nist_Any_2_Terminated_X_cancel"),
+
+ TSK_FSM_ADD_NULL());
+
+ /* Set callback function to call when new messages arrive or errors happen at
+ the transport layer.
+ */
+ TSIP_TRANSAC(self)->callback = TSIP_TRANSAC_EVENT_CALLBACK_F(tsip_transac_nist_event_callback);
+
+ return 0;
}
tsip_transac_nist_t* tsip_transac_nist_create(int32_t cseq_value, const char* cseq_method, const char* callid, tsip_transac_dst_t* dst)
{
- tsip_transac_nist_t* transac = tsk_object_new(tsip_transac_nist_def_t);
-
- if(transac){
- // initialize base class
- tsip_transac_init(TSIP_TRANSAC(transac), tsip_transac_type_nist, cseq_value, cseq_method, callid, dst, _fsm_state_Started, _fsm_state_Terminated);
-
- // init FSM
- TSIP_TRANSAC_GET_FSM(transac)->debug = DEBUG_STATE_MACHINE;
- tsk_fsm_set_callback_terminated(TSIP_TRANSAC_GET_FSM(transac), TSK_FSM_ONTERMINATED_F(tsip_transac_nist_OnTerminated), (const void*)transac);
-
- // initialize NICT object
- tsip_transac_nist_init(transac);
- }
- return transac;
+ tsip_transac_nist_t* transac = tsk_object_new(tsip_transac_nist_def_t);
+
+ if(transac) {
+ // initialize base class
+ tsip_transac_init(TSIP_TRANSAC(transac), tsip_transac_type_nist, cseq_value, cseq_method, callid, dst, _fsm_state_Started, _fsm_state_Terminated);
+
+ // init FSM
+ TSIP_TRANSAC_GET_FSM(transac)->debug = DEBUG_STATE_MACHINE;
+ tsk_fsm_set_callback_terminated(TSIP_TRANSAC_GET_FSM(transac), TSK_FSM_ONTERMINATED_F(tsip_transac_nist_OnTerminated), (const void*)transac);
+
+ // initialize NICT object
+ tsip_transac_nist_init(transac);
+ }
+ return transac;
}
int tsip_transac_nist_start(tsip_transac_nist_t *self, const tsip_request_t* request)
{
- int ret = -1;
-
- if(self && !TSIP_TRANSAC(self)->running && request){
- TSIP_TRANSAC(self)->running = 1;
- if((ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_request, request))){
- //
- }
- }
- return ret;
+ int ret = -1;
+
+ if(self && !TSIP_TRANSAC(self)->running && request) {
+ TSIP_TRANSAC(self)->running = 1;
+ if((ret = tsip_transac_fsm_act(TSIP_TRANSAC(self), _fsm_action_request, request))) {
+ //
+ }
+ }
+ return ret;
}
@@ -299,206 +291,206 @@ int tsip_transac_nist_start(tsip_transac_nist_t *self, const tsip_request_t* req
*/
int tsip_transac_nist_Started_2_Trying_X_request(va_list *app)
{
- tsip_transac_nist_t *self = va_arg(*app, tsip_transac_nist_t *);
- const tsip_request_t *request = va_arg(*app, const tsip_request_t *);
-
- if(TNET_SOCKET_TYPE_IS_VALID(request->src_net_type)){
- TSIP_TRANSAC(self)->reliable = TNET_SOCKET_TYPE_IS_STREAM(request->src_net_type);
- }
-
- /* Set Timers */
- self->timerJ.timeout = TSIP_TRANSAC(self)->reliable ? 0 : TSIP_TIMER_GET(J); /* RFC 3261 - 17.2.2*/
-
- /* RFC 3261 - 17.2.2
- The state machine is initialized in the "Trying" state and is passed
- a request other than INVITE or ACK when initialized. This request is
- passed up to the TU. Once in the "Trying" state, any further request
- retransmissions are discarded. A request is a retransmission if it
- matches the same server transaction, using the rules specified in
- Section 17.2.3.
- */
- return tsip_transac_deliver(TSIP_TRANSAC(self), tsip_dialog_i_msg, request);
+ tsip_transac_nist_t *self = va_arg(*app, tsip_transac_nist_t *);
+ const tsip_request_t *request = va_arg(*app, const tsip_request_t *);
+
+ if(TNET_SOCKET_TYPE_IS_VALID(request->src_net_type)) {
+ TSIP_TRANSAC(self)->reliable = TNET_SOCKET_TYPE_IS_STREAM(request->src_net_type);
+ }
+
+ /* Set Timers */
+ self->timerJ.timeout = TSIP_TRANSAC(self)->reliable ? 0 : TSIP_TIMER_GET(J); /* RFC 3261 - 17.2.2*/
+
+ /* RFC 3261 - 17.2.2
+ The state machine is initialized in the "Trying" state and is passed
+ a request other than INVITE or ACK when initialized. This request is
+ passed up to the TU. Once in the "Trying" state, any further request
+ retransmissions are discarded. A request is a retransmission if it
+ matches the same server transaction, using the rules specified in
+ Section 17.2.3.
+ */
+ return tsip_transac_deliver(TSIP_TRANSAC(self), tsip_dialog_i_msg, request);
}
/* Trying --> (1xx) --> Proceeding
*/
int tsip_transac_nist_Trying_2_Proceeding_X_send_1xx(va_list *app)
{
- tsip_transac_nist_t *self = va_arg(*app, tsip_transac_nist_t *);
- const tsip_response_t *response = va_arg(*app, const tsip_response_t *);
- int ret;
-
- /* RFC 3261 - 17.2.2
- While in the "Trying" state, if the TU passes a provisional response
- to the server transaction, the server transaction MUST enter the
- "Proceeding" state. The response MUST be passed to the transport
- layer for transmission.
- */
- ret = tsip_transac_send(TSIP_TRANSAC(self), TSIP_TRANSAC(self)->branch, TSIP_MESSAGE(response));
-
- /* Update last response */
- TRANSAC_NIST_SET_LAST_RESPONSE(self, response);
-
- return ret;
+ tsip_transac_nist_t *self = va_arg(*app, tsip_transac_nist_t *);
+ const tsip_response_t *response = va_arg(*app, const tsip_response_t *);
+ int ret;
+
+ /* RFC 3261 - 17.2.2
+ While in the "Trying" state, if the TU passes a provisional response
+ to the server transaction, the server transaction MUST enter the
+ "Proceeding" state. The response MUST be passed to the transport
+ layer for transmission.
+ */
+ ret = tsip_transac_send(TSIP_TRANSAC(self), TSIP_TRANSAC(self)->branch, TSIP_MESSAGE(response));
+
+ /* Update last response */
+ TRANSAC_NIST_SET_LAST_RESPONSE(self, response);
+
+ return ret;
}
/* Trying --> (200-699) --> Completed
*/
int tsip_transac_nist_Trying_2_Completed_X_send_200_to_699(va_list *app)
{
- tsip_transac_nist_t *self = va_arg(*app, tsip_transac_nist_t *);
- const tsip_response_t *response = va_arg(*app, const tsip_response_t *);
- int ret;
+ tsip_transac_nist_t *self = va_arg(*app, tsip_transac_nist_t *);
+ const tsip_response_t *response = va_arg(*app, const tsip_response_t *);
+ int ret;
- ret = tsip_transac_send(TSIP_TRANSAC(self), TSIP_TRANSAC(self)->branch, TSIP_MESSAGE(response));
+ ret = tsip_transac_send(TSIP_TRANSAC(self), TSIP_TRANSAC(self)->branch, TSIP_MESSAGE(response));
- /* RFC 3261 - 17.2.2
- When the server transaction enters the "Completed" state, it MUST set
- Timer J to fire in 64*T1 seconds for unreliable transports, and zero
- seconds for reliable transports.
- */
- TRANSAC_NIST_TIMER_SCHEDULE(J);
+ /* RFC 3261 - 17.2.2
+ When the server transaction enters the "Completed" state, it MUST set
+ Timer J to fire in 64*T1 seconds for unreliable transports, and zero
+ seconds for reliable transports.
+ */
+ TRANSAC_NIST_TIMER_SCHEDULE(J);
- /* Update last response */
- TRANSAC_NIST_SET_LAST_RESPONSE(self, response);
+ /* Update last response */
+ TRANSAC_NIST_SET_LAST_RESPONSE(self, response);
- return ret;
+ return ret;
}
/* Proceeding --> (1xx) --> Proceeding
*/
int tsip_transac_nist_Proceeding_2_Proceeding_X_send_1xx(va_list *app)
{
- tsip_transac_nist_t *self = va_arg(*app, tsip_transac_nist_t *);
- const tsip_response_t *response = va_arg(*app, const tsip_response_t *);
+ tsip_transac_nist_t *self = va_arg(*app, tsip_transac_nist_t *);
+ const tsip_response_t *response = va_arg(*app, const tsip_response_t *);
- /* RFC 3261 - 17.2.2
- Any further provisional responses that are
- received from the TU while in the "Proceeding" state MUST be passed
- to the transport layer for transmission.
- */
- tsip_transac_send(TSIP_TRANSAC(self), TSIP_TRANSAC(self)->branch, TSIP_MESSAGE(response));
+ /* RFC 3261 - 17.2.2
+ Any further provisional responses that are
+ received from the TU while in the "Proceeding" state MUST be passed
+ to the transport layer for transmission.
+ */
+ tsip_transac_send(TSIP_TRANSAC(self), TSIP_TRANSAC(self)->branch, TSIP_MESSAGE(response));
- /* Update last response */
- TRANSAC_NIST_SET_LAST_RESPONSE(self, response);
+ /* Update last response */
+ TRANSAC_NIST_SET_LAST_RESPONSE(self, response);
- return 0;
+ return 0;
}
/* Proceeding -> (INCOMING REQUEST) -> Proceeding
*/
int tsip_transac_nist_Proceeding_2_Proceeding_X_request(va_list *app)
{
- tsip_transac_nist_t *self = va_arg(*app, tsip_transac_nist_t *);
- /*const tsip_response_t *response = va_arg(*app, const tsip_response_t *);*/
-
- /* RFC 3261 - 17.2.2
- If a retransmission of the request is received while in the "Proceeding" state, the most
- recently sent provisional response MUST be passed to the transport
- layer for retransmission.
- */
- if(self->lastResponse){
- tsip_transac_send(TSIP_TRANSAC(self), TSIP_TRANSAC(self)->branch, self->lastResponse);
- }
-
- return 0;
+ tsip_transac_nist_t *self = va_arg(*app, tsip_transac_nist_t *);
+ /*const tsip_response_t *response = va_arg(*app, const tsip_response_t *);*/
+
+ /* RFC 3261 - 17.2.2
+ If a retransmission of the request is received while in the "Proceeding" state, the most
+ recently sent provisional response MUST be passed to the transport
+ layer for retransmission.
+ */
+ if(self->lastResponse) {
+ tsip_transac_send(TSIP_TRANSAC(self), TSIP_TRANSAC(self)->branch, self->lastResponse);
+ }
+
+ return 0;
}
/* Proceeding --> (200-699) --> Completed
*/
int tsip_transac_nist_Proceeding_2_Completed_X_send_200_to_699(va_list *app)
{
- tsip_transac_nist_t *self = va_arg(*app, tsip_transac_nist_t *);
- const tsip_response_t *response = va_arg(*app, const tsip_response_t *);
- int ret;
-
- /* RFC 3261 - 17.2.2
- If the TU passes a final response (status
- codes 200-699) to the server while in the "Proceeding" state, the
- transaction MUST enter the "Completed" state, and the response MUST
- be passed to the transport layer for transmission.
- */
- ret = tsip_transac_send(TSIP_TRANSAC(self), TSIP_TRANSAC(self)->branch, TSIP_MESSAGE(response));
-
- /* RFC 3261 - 17.2.2
- When the server transaction enters the "Completed" state, it MUST set
- Timer J to fire in 64*T1 seconds for unreliable transports, and zero
- seconds for reliable transports.
- */
- TRANSAC_NIST_TIMER_SCHEDULE(J);
-
- /* Update last response */
- TRANSAC_NIST_SET_LAST_RESPONSE(self, response);
-
- return ret;
+ tsip_transac_nist_t *self = va_arg(*app, tsip_transac_nist_t *);
+ const tsip_response_t *response = va_arg(*app, const tsip_response_t *);
+ int ret;
+
+ /* RFC 3261 - 17.2.2
+ If the TU passes a final response (status
+ codes 200-699) to the server while in the "Proceeding" state, the
+ transaction MUST enter the "Completed" state, and the response MUST
+ be passed to the transport layer for transmission.
+ */
+ ret = tsip_transac_send(TSIP_TRANSAC(self), TSIP_TRANSAC(self)->branch, TSIP_MESSAGE(response));
+
+ /* RFC 3261 - 17.2.2
+ When the server transaction enters the "Completed" state, it MUST set
+ Timer J to fire in 64*T1 seconds for unreliable transports, and zero
+ seconds for reliable transports.
+ */
+ TRANSAC_NIST_TIMER_SCHEDULE(J);
+
+ /* Update last response */
+ TRANSAC_NIST_SET_LAST_RESPONSE(self, response);
+
+ return ret;
}
/* Completed --> (INCOMING REQUEST) --> Completed
*/
int tsip_transac_nist_Completed_2_Completed_X_request(va_list *app)
{
- tsip_transac_nist_t *self = va_arg(*app, tsip_transac_nist_t *);
- /*const tsip_response_t *response = va_arg(*app, const tsip_response_t *);*/
-
- /* RFC 3261 - 17.2.2
- While in the "Completed" state, the server transaction MUST pass the final response to the transport
- layer for retransmission whenever a retransmission of the request is received.
- */
- if(self->lastResponse){
- tsip_transac_send(TSIP_TRANSAC(self), TSIP_TRANSAC(self)->branch, self->lastResponse);
- }
-
- return 0;
+ tsip_transac_nist_t *self = va_arg(*app, tsip_transac_nist_t *);
+ /*const tsip_response_t *response = va_arg(*app, const tsip_response_t *);*/
+
+ /* RFC 3261 - 17.2.2
+ While in the "Completed" state, the server transaction MUST pass the final response to the transport
+ layer for retransmission whenever a retransmission of the request is received.
+ */
+ if(self->lastResponse) {
+ tsip_transac_send(TSIP_TRANSAC(self), TSIP_TRANSAC(self)->branch, self->lastResponse);
+ }
+
+ return 0;
}
/* Complete --> (Timer J) --> Terminated
*/
int tsip_transac_nist_Completed_2_Terminated_X_tirmerJ(va_list *app)
{
- /*tsip_transac_nist_t *self = va_arg(*app, tsip_transac_nist_t *);*/
- /*const tsip_response_t *response = va_arg(*app, const tsip_response_t *);*/
-
- /* RFC 3261 - 17.2.2
- The server transaction remains in this state (Completed) until Timer J fires, at
- which point it MUST transition to the "Terminated" state.
- */
-
- /* RFC 3261 - 17.2.2
- THE SERVER TRANSACTION MUST BE DESTROYED THE INSTANT IT ENTERS THE "TERMINATED" STATE.
- */
- return 0;
+ /*tsip_transac_nist_t *self = va_arg(*app, tsip_transac_nist_t *);*/
+ /*const tsip_response_t *response = va_arg(*app, const tsip_response_t *);*/
+
+ /* RFC 3261 - 17.2.2
+ The server transaction remains in this state (Completed) until Timer J fires, at
+ which point it MUST transition to the "Terminated" state.
+ */
+
+ /* RFC 3261 - 17.2.2
+ THE SERVER TRANSACTION MUST BE DESTROYED THE INSTANT IT ENTERS THE "TERMINATED" STATE.
+ */
+ return 0;
}
/* Any -> (Transport Error) -> Terminated
*/
int tsip_transac_nist_Any_2_Terminated_X_transportError(va_list *app)
{
- tsip_transac_nist_t *self = va_arg(*app, tsip_transac_nist_t *);
- //const tsip_message_t *message = va_arg(*app, const tsip_message_t *);
+ tsip_transac_nist_t *self = va_arg(*app, tsip_transac_nist_t *);
+ //const tsip_message_t *message = va_arg(*app, const tsip_message_t *);
- /* Timers will be canceled by "tsip_transac_nict_OnTerminated" */
+ /* Timers will be canceled by "tsip_transac_nict_OnTerminated" */
- return tsip_transac_deliver(TSIP_TRANSAC(self), tsip_dialog_transport_error, tsk_null);
+ return tsip_transac_deliver(TSIP_TRANSAC(self), tsip_dialog_transport_error, tsk_null);
}
/* Any -> (Error) -> Terminated
*/
int tsip_transac_nist_Any_2_Terminated_X_Error(va_list *app)
{
- tsip_transac_nist_t *self = va_arg(*app, tsip_transac_nist_t *);
- //const tsip_message_t *message = va_arg(*app, const tsip_message_t *);
+ tsip_transac_nist_t *self = va_arg(*app, tsip_transac_nist_t *);
+ //const tsip_message_t *message = va_arg(*app, const tsip_message_t *);
- /* Timers will be canceled by "tsip_transac_nict_OnTerminated" */
+ /* Timers will be canceled by "tsip_transac_nict_OnTerminated" */
- return tsip_transac_deliver(TSIP_TRANSAC(self), tsip_dialog_error, tsk_null);
+ return tsip_transac_deliver(TSIP_TRANSAC(self), tsip_dialog_error, tsk_null);
}
/* Any -> (cancel) -> Terminated
*/
int tsip_transac_nist_Any_2_Terminated_X_cancel(va_list *app)
{
- /* doubango-specific */
- return 0;
+ /* doubango-specific */
+ return 0;
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++
@@ -513,10 +505,10 @@ int tsip_transac_nist_Any_2_Terminated_X_cancel(va_list *app)
*/
int tsip_transac_nist_OnTerminated(tsip_transac_nist_t *self)
{
- TSK_DEBUG_INFO("=== NIST terminated ===");
-
- /* Remove (and destroy) the transaction from the layer. */
- return tsip_transac_remove(TSIP_TRANSAC(self));
+ TSK_DEBUG_INFO("=== NIST terminated ===");
+
+ /* Remove (and destroy) the transaction from the layer. */
+ return tsip_transac_remove(TSIP_TRANSAC(self));
}
@@ -544,40 +536,39 @@ int tsip_transac_nist_OnTerminated(tsip_transac_nist_t *self)
//
static tsk_object_t* tsip_transac_nist_ctor(tsk_object_t * self, va_list * app)
{
- tsip_transac_nist_t *transac = self;
- if(transac){
- }
- return self;
+ tsip_transac_nist_t *transac = self;
+ if(transac) {
+ }
+ return self;
}
static tsk_object_t* tsip_transac_nist_dtor(tsk_object_t * _self)
-{
- tsip_transac_nist_t *self = _self;
- if(self){
- /* Cancel timers */
- TRANSAC_TIMER_CANCEL(J);
+{
+ tsip_transac_nist_t *self = _self;
+ if(self) {
+ /* Cancel timers */
+ TRANSAC_TIMER_CANCEL(J);
- TSIP_TRANSAC(self)->running = tsk_false;
- TSK_OBJECT_SAFE_FREE(self->lastResponse);
+ TSIP_TRANSAC(self)->running = tsk_false;
+ TSK_OBJECT_SAFE_FREE(self->lastResponse);
- /* DeInitialize base class */
- tsip_transac_deinit(TSIP_TRANSAC(self));
+ /* DeInitialize base class */
+ tsip_transac_deinit(TSIP_TRANSAC(self));
- TSK_DEBUG_INFO("*** NIST destroyed ***");
- }
- return _self;
+ TSK_DEBUG_INFO("*** NIST destroyed ***");
+ }
+ return _self;
}
static int tsip_transac_nist_cmp(const tsk_object_t *t1, const tsk_object_t *t2)
{
- return tsip_transac_cmp(t1, t2);
+ return tsip_transac_cmp(t1, t2);
}
-static const tsk_object_def_t tsip_transac_nist_def_s =
-{
- sizeof(tsip_transac_nist_t),
- tsip_transac_nist_ctor,
- tsip_transac_nist_dtor,
- tsip_transac_nist_cmp,
+static const tsk_object_def_t tsip_transac_nist_def_s = {
+ sizeof(tsip_transac_nist_t),
+ tsip_transac_nist_ctor,
+ tsip_transac_nist_dtor,
+ tsip_transac_nist_cmp,
};
const tsk_object_def_t *tsip_transac_nist_def_t = &tsip_transac_nist_def_s;
OpenPOWER on IntegriCloud