📄 ist_fsm.c
字号:
/* The oSIP library implements the Session Initiation Protocol (SIP -rfc3261-) Copyright (C) 2001,2002,2003,2004,2005,2006,2007 Aymeric MOIZARD jack@atosc.org This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*/#include <osip2/internal.h>#include <osip2/osip.h>#include "fsm.h"#ifndef MINISIZEosip_statemachine_t *ist_fsm;osip_statemachine_t *__ist_get_fsm (){ return ist_fsm;}void__ist_unload_fsm (){ transition_t *transition; osip_statemachine_t *statemachine = __ist_get_fsm (); for (transition = statemachine->transitions; transition != NULL; transition = statemachine->transitions) { REMOVE_ELEMENT(statemachine->transitions, transition); osip_free (transition); } osip_free (statemachine->transitions); osip_free (statemachine);}void__ist_load_fsm (){ transition_t *transition; ist_fsm = (osip_statemachine_t *) osip_malloc (sizeof (osip_statemachine_t)); ist_fsm->transitions = NULL; transition = (transition_t *) osip_malloc (sizeof (transition_t)); transition->state = IST_PRE_PROCEEDING; transition->type = RCV_REQINVITE; transition->method = (void (*)(void *, void *)) &ist_rcv_invite; ADD_ELEMENT (ist_fsm->transitions, transition); transition = (transition_t *) osip_malloc (sizeof (transition_t)); transition->state = IST_PROCEEDING; transition->type = RCV_REQINVITE; transition->method = (void (*)(void *, void *)) &ist_rcv_invite; ADD_ELEMENT (ist_fsm->transitions, transition); transition = (transition_t *) osip_malloc (sizeof (transition_t)); transition->state = IST_COMPLETED; transition->type = RCV_REQINVITE; transition->method = (void (*)(void *, void *)) &ist_rcv_invite; ADD_ELEMENT (ist_fsm->transitions, transition); transition = (transition_t *) osip_malloc (sizeof (transition_t)); transition->state = IST_COMPLETED; transition->type = TIMEOUT_G; transition->method = (void (*)(void *, void *)) &osip_ist_timeout_g_event; ADD_ELEMENT (ist_fsm->transitions, transition); transition = (transition_t *) osip_malloc (sizeof (transition_t)); transition->state = IST_COMPLETED; transition->type = TIMEOUT_H; transition->method = (void (*)(void *, void *)) &osip_ist_timeout_h_event; ADD_ELEMENT (ist_fsm->transitions, transition); transition = (transition_t *) osip_malloc (sizeof (transition_t)); transition->state = IST_PROCEEDING; transition->type = SND_STATUS_1XX; transition->method = (void (*)(void *, void *)) &ist_snd_1xx; ADD_ELEMENT (ist_fsm->transitions, transition); transition = (transition_t *) osip_malloc (sizeof (transition_t)); transition->state = IST_PROCEEDING; transition->type = SND_STATUS_2XX; transition->method = (void (*)(void *, void *)) &ist_snd_2xx; ADD_ELEMENT (ist_fsm->transitions, transition); transition = (transition_t *) osip_malloc (sizeof (transition_t)); transition->state = IST_PROCEEDING; transition->type = SND_STATUS_3456XX; transition->method = (void (*)(void *, void *)) &ist_snd_3456xx; ADD_ELEMENT (ist_fsm->transitions, transition); transition = (transition_t *) osip_malloc (sizeof (transition_t)); transition->state = IST_COMPLETED; transition->type = RCV_REQACK; transition->method = (void (*)(void *, void *)) &ist_rcv_ack; ADD_ELEMENT (ist_fsm->transitions, transition); transition = (transition_t *) osip_malloc (sizeof (transition_t)); transition->state = IST_CONFIRMED; transition->type = RCV_REQACK; transition->method = (void (*)(void *, void *)) &ist_rcv_ack; ADD_ELEMENT (ist_fsm->transitions, transition); transition = (transition_t *) osip_malloc (sizeof (transition_t)); transition->state = IST_CONFIRMED; transition->type = TIMEOUT_I; transition->method = (void (*)(void *, void *)) &osip_ist_timeout_i_event; ADD_ELEMENT (ist_fsm->transitions, transition);}#elsetransition_t ist_transition[11] = { { IST_PRE_PROCEEDING, RCV_REQINVITE, (void (*)(void *, void *)) &ist_rcv_invite, &ist_transition[1], NULL } , { IST_PROCEEDING, RCV_REQINVITE, (void (*)(void *, void *)) &ist_rcv_invite, &ist_transition[2], NULL } , { IST_COMPLETED, RCV_REQINVITE, (void (*)(void *, void *)) &ist_rcv_invite, &ist_transition[3], NULL } , { IST_COMPLETED, TIMEOUT_G, (void (*)(void *, void *)) &osip_ist_timeout_g_event, &ist_transition[4], NULL } , { IST_COMPLETED, TIMEOUT_H, (void (*)(void *, void *)) &osip_ist_timeout_h_event, &ist_transition[5], NULL } , { IST_PROCEEDING, SND_STATUS_1XX, (void (*)(void *, void *)) &ist_snd_1xx, &ist_transition[6], NULL } , { IST_PROCEEDING, SND_STATUS_2XX, (void (*)(void *, void *)) &ist_snd_2xx, &ist_transition[7], NULL } , { IST_PROCEEDING, SND_STATUS_3456XX, (void (*)(void *, void *)) &ist_snd_3456xx, &ist_transition[8], NULL } , { IST_COMPLETED, RCV_REQACK, (void (*)(void *, void *)) &ist_rcv_ack, &ist_transition[9], NULL } , { IST_CONFIRMED, RCV_REQACK, (void (*)(void *, void *)) &ist_rcv_ack, &ist_transition[10], NULL } , { IST_CONFIRMED, TIMEOUT_I, (void (*)(void *, void *)) &osip_ist_timeout_i_event, NULL, NULL } };osip_statemachine_t ist_fsm = { ist_transition };#endifstatic voidist_handle_transport_error (osip_transaction_t * ist, int err){ __osip_transport_error_callback (OSIP_IST_TRANSPORT_ERROR, ist, err); __osip_transaction_set_state (ist, IST_TERMINATED); __osip_kill_transaction_callback (OSIP_IST_KILL_TRANSACTION, ist); /* TODO: MUST BE DELETED NOW */}voidist_rcv_invite (osip_transaction_t * ist, osip_event_t * evt){ int i; if (ist->state == IST_PRE_PROCEEDING) /* announce new INVITE */ { /* Here we have ist->orig_request == NULL */ ist->orig_request = evt->sip; __osip_message_callback (OSIP_IST_INVITE_RECEIVED, ist, evt->sip); } else /* IST_PROCEEDING or IST_COMPLETED */ { /* delete retransmission */ osip_message_free (evt->sip); __osip_message_callback (OSIP_IST_INVITE_RECEIVED_AGAIN, ist, ist->orig_request); if (ist->last_response != NULL) /* retransmit last response */ { i = __osip_transaction_snd_xxx(ist, ist->last_response); if (i != 0) { ist_handle_transport_error (ist, i); return; } else { if (MSG_IS_STATUS_1XX (ist->last_response)) __osip_message_callback (OSIP_IST_STATUS_1XX_SENT, ist, ist->last_response); else if (MSG_IS_STATUS_2XX (ist->last_response)) __osip_message_callback (OSIP_IST_STATUS_2XX_SENT_AGAIN, ist, ist->last_response); else __osip_message_callback (OSIP_IST_STATUS_3456XX_SENT_AGAIN, ist, ist->last_response); } } return; } /* we come here only if it was the first INVITE received */ __osip_transaction_set_state (ist, IST_PROCEEDING);}voidosip_ist_timeout_g_event (osip_transaction_t * ist, osip_event_t * evt){ int i; ist->ist_context->timer_g_length = ist->ist_context->timer_g_length * 2; if (ist->ist_context->timer_g_length > 4000) ist->ist_context->timer_g_length = 4000; osip_gettimeofday (&ist->ist_context->timer_g_start, NULL); add_gettimeofday (&ist->ist_context->timer_g_start, ist->ist_context->timer_g_length); i = __osip_transaction_snd_xxx(ist, ist->last_response); if (i != 0) { ist_handle_transport_error (ist, i); return; } __osip_message_callback (OSIP_IST_STATUS_3456XX_SENT_AGAIN, ist, ist->last_response);}voidosip_ist_timeout_h_event (osip_transaction_t * ist, osip_event_t * evt){ ist->ist_context->timer_h_length = -1; ist->ist_context->timer_h_start.tv_sec = -1; __osip_transaction_set_state (ist, IST_TERMINATED); __osip_kill_transaction_callback (OSIP_IST_KILL_TRANSACTION, ist);}voidosip_ist_timeout_i_event (osip_transaction_t * ist, osip_event_t * evt){ ist->ist_context->timer_i_length = -1; ist->ist_context->timer_i_start.tv_sec = -1; __osip_transaction_set_state (ist, IST_TERMINATED); __osip_kill_transaction_callback (OSIP_IST_KILL_TRANSACTION, ist);}voidist_snd_1xx (osip_transaction_t * ist, osip_event_t * evt){ int i; if (ist->last_response != NULL) { osip_message_free (ist->last_response); } ist->last_response = evt->sip; i = __osip_transaction_snd_xxx(ist, evt->sip); if (i != 0) { ist_handle_transport_error (ist, i); return; } else __osip_message_callback (OSIP_IST_STATUS_1XX_SENT, ist, ist->last_response); /* we are already in the proper state */ return;}voidist_snd_2xx (osip_transaction_t * ist, osip_event_t * evt){ int i; if (ist->last_response != NULL) { osip_message_free (ist->last_response); } ist->last_response = evt->sip; i = __osip_transaction_snd_xxx(ist, evt->sip); if (i != 0) { ist_handle_transport_error (ist, i); return; } else { __osip_message_callback (OSIP_IST_STATUS_2XX_SENT, ist, ist->last_response); __osip_transaction_set_state (ist, IST_TERMINATED); __osip_kill_transaction_callback (OSIP_IST_KILL_TRANSACTION, ist); } return;}voidist_snd_3456xx (osip_transaction_t * ist, osip_event_t * evt){ int i; if (ist->last_response != NULL) { osip_message_free (ist->last_response); } ist->last_response = evt->sip; i = __osip_transaction_snd_xxx(ist, evt->sip); if (i != 0) { ist_handle_transport_error (ist, i); return; } else { if (MSG_IS_STATUS_3XX (ist->last_response)) __osip_message_callback (OSIP_IST_STATUS_3XX_SENT, ist, ist->last_response); else if (MSG_IS_STATUS_4XX (ist->last_response)) __osip_message_callback (OSIP_IST_STATUS_4XX_SENT, ist, ist->last_response); else if (MSG_IS_STATUS_5XX (ist->last_response)) __osip_message_callback (OSIP_IST_STATUS_5XX_SENT, ist, ist->last_response); else __osip_message_callback (OSIP_IST_STATUS_6XX_SENT, ist, ist->last_response); } if (ist->ist_context->timer_g_length != -1) { osip_gettimeofday (&ist->ist_context->timer_g_start, NULL); add_gettimeofday (&ist->ist_context->timer_g_start, ist->ist_context->timer_g_length); } osip_gettimeofday (&ist->ist_context->timer_h_start, NULL); add_gettimeofday (&ist->ist_context->timer_h_start, ist->ist_context->timer_h_length); __osip_transaction_set_state (ist, IST_COMPLETED); return;}voidist_rcv_ack (osip_transaction_t * ist, osip_event_t * evt){ if (ist->ack != NULL) { osip_message_free (ist->ack); } ist->ack = evt->sip; if (ist->state == IST_COMPLETED) __osip_message_callback (OSIP_IST_ACK_RECEIVED, ist, ist->ack); else /* IST_CONFIRMED */ __osip_message_callback (OSIP_IST_ACK_RECEIVED_AGAIN, ist, ist->ack); /* set the timer to 0 for reliable, and T4 for unreliable (already set) */ osip_gettimeofday (&ist->ist_context->timer_i_start, NULL); add_gettimeofday (&ist->ist_context->timer_i_start, ist->ist_context->timer_i_length); __osip_transaction_set_state (ist, IST_CONFIRMED);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -