⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ist_fsm.c

📁 libosip2-3.0.3最新版本
💻 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 + -