📄 osip.c
字号:
/* The oSIP library implements the Session Initiation Protocol (SIP -rfc3261-) Copyright (C) 2001,2002,2003 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 <osip/port.h>#include <osip/osip.h>#include "fsm.h"#ifdef OSIP_MTstatic smutex_t *ict_fastmutex;static smutex_t *ist_fastmutex;static smutex_t *nict_fastmutex;static smutex_t *nist_fastmutex;#endifintosip_global_init (){ /* load the fsm configuration */ ict_load_fsm (); ist_load_fsm (); nict_load_fsm (); nist_load_fsm (); /* load the parser configuration */ parser_init (); /* give a seed for all calls to rand() */ srand (time (NULL)); init_random_number ();#ifdef OSIP_MT ict_fastmutex = smutex_init (); ist_fastmutex = smutex_init (); nict_fastmutex = smutex_init (); nist_fastmutex = smutex_init ();#endif return 0;}voidosip_global_free (){ ict_unload_fsm (); ist_unload_fsm (); nict_unload_fsm (); nist_unload_fsm ();#ifdef OSIP_MT smutex_destroy (ict_fastmutex); sfree (ict_fastmutex); smutex_destroy (ist_fastmutex); sfree (ist_fastmutex); smutex_destroy (nict_fastmutex); sfree (nict_fastmutex); smutex_destroy (nist_fastmutex); sfree (nist_fastmutex);#endif}intosip_ict_lock (osip_t * osip){#ifdef OSIP_MT return smutex_lock (ict_fastmutex);#else return 0;#endif}intosip_ict_unlock (osip_t * osip){#ifdef OSIP_MT return smutex_unlock (ict_fastmutex);#else return 0;#endif}intosip_ist_lock (osip_t * osip){#ifdef OSIP_MT return smutex_lock (ist_fastmutex);#else return 0;#endif}intosip_ist_unlock (osip_t * osip){#ifdef OSIP_MT return smutex_unlock (ist_fastmutex);#else return 0;#endif}intosip_nict_lock (osip_t * osip){#ifdef OSIP_MT return smutex_lock (nict_fastmutex);#else return 0;#endif}intosip_nict_unlock (osip_t * osip){#ifdef OSIP_MT return smutex_unlock (nict_fastmutex);#else return 0;#endif}intosip_nist_lock (osip_t * osip){#ifdef OSIP_MT return smutex_lock (nist_fastmutex);#else return 0;#endif}intosip_nist_unlock (osip_t * osip){#ifdef OSIP_MT return smutex_unlock (nist_fastmutex);#else return 0;#endif}intosip_add_ict (osip_t * osip, transaction_t * ict){#ifdef OSIP_MT smutex_lock (ict_fastmutex);#endif list_add (osip->ict_transactions, ict, -1);#ifdef OSIP_MT smutex_unlock (ict_fastmutex);#endif return 0;}intosip_add_ist (osip_t * osip, transaction_t * ist){#ifdef OSIP_MT smutex_lock (ist_fastmutex);#endif list_add (osip->ist_transactions, ist, -1);#ifdef OSIP_MT smutex_unlock (ist_fastmutex);#endif return 0;}intosip_add_nict (osip_t * osip, transaction_t * nict){#ifdef OSIP_MT smutex_lock (nict_fastmutex);#endif list_add (osip->nict_transactions, nict, -1);#ifdef OSIP_MT smutex_unlock (nict_fastmutex);#endif return 0;}intosip_add_nist (osip_t * osip, transaction_t * nist){#ifdef OSIP_MT smutex_lock (nist_fastmutex);#endif list_add (osip->nist_transactions, nist, -1);#ifdef OSIP_MT smutex_unlock (nist_fastmutex);#endif return 0;}intosip_remove_ict (osip_t * osip, transaction_t * ict){ int pos = 0; transaction_t *tmp;#ifdef OSIP_MT smutex_lock (ict_fastmutex);#endif while (!list_eol (osip->ict_transactions, pos)) { tmp = list_get (osip->ict_transactions, pos); if (tmp->transactionid == ict->transactionid) { list_remove (osip->ict_transactions, pos);#ifdef OSIP_MT smutex_unlock (ict_fastmutex);#endif return 0; } pos++; }#ifdef OSIP_MT smutex_unlock (ict_fastmutex);#endif return -1;}intosip_remove_ist (osip_t * osip, transaction_t * ist){ int pos = 0; transaction_t *tmp;#ifdef OSIP_MT smutex_lock (ist_fastmutex);#endif while (!list_eol (osip->ist_transactions, pos)) { tmp = list_get (osip->ist_transactions, pos); if (tmp->transactionid == ist->transactionid) { list_remove (osip->ist_transactions, pos);#ifdef OSIP_MT smutex_unlock (ist_fastmutex);#endif return 0; } pos++; }#ifdef OSIP_MT smutex_unlock (ist_fastmutex);#endif return -1;}intosip_remove_nict (osip_t * osip, transaction_t * nict){ int pos = 0; transaction_t *tmp;#ifdef OSIP_MT smutex_lock (nict_fastmutex);#endif while (!list_eol (osip->nict_transactions, pos)) { tmp = list_get (osip->nict_transactions, pos); if (tmp->transactionid == nict->transactionid) { list_remove (osip->nict_transactions, pos);#ifdef OSIP_MT smutex_unlock (nict_fastmutex);#endif return 0; } pos++; }#ifdef OSIP_MT smutex_unlock (nict_fastmutex);#endif return -1;}intosip_remove_nist (osip_t * osip, transaction_t * nist){ int pos = 0; transaction_t *tmp;#ifdef OSIP_MT smutex_lock (nist_fastmutex);#endif while (!list_eol (osip->nist_transactions, pos)) { tmp = list_get (osip->nist_transactions, pos); if (tmp->transactionid == nist->transactionid) { list_remove (osip->nist_transactions, pos);#ifdef OSIP_MT smutex_unlock (nist_fastmutex);#endif return 0; } pos++; }#ifdef OSIP_MT smutex_unlock (nist_fastmutex);#endif return -1;}#if 0/* this method is made obsolete because it contains bugs and is also too much limited. any call to this method should be replace this way: //osip_distribute(osip, evt); transaction_t *transaction = osip_find_transaction_and_add_event(osip, evt); if (i!=0) // in case it's a new request { if (evt is an ACK) evt could be an ACK for INVITE (not handled by oSIP) else if ( evt is a 200 for INVITE) evt could be a retransmission of a 200 for INVITE (not handled by oSIP) else if (evt is a new request) == not a ACK and not a response { transaction = osip_create_transaction(osip, evt); if (transaction==NULL) printf("failed to create a transaction\"); } } else { // here, the message as been taken by the stack. }*//* finds the transaction context and add the sipevent in its fifo. *//* USED ONLY BY THE TRANSPORT LAYER. *//* INPUT : osip_t *osip | osip. contains the list of tr. context*//* INPUT : sipevent_t* sipevent | event to dispatch. */transaction_t *osip_distribute_event (osip_t * osip, sipevent_t * evt){ transaction_t *transaction = NULL; int i; context_type_t ctx_type; if (EVT_IS_INCOMINGMSG (evt)) { /* event is for ict */ if (MSG_IS_REQUEST (evt->sip)) { if (0 == strcmp (evt->sip->cseq->method, "INVITE") || 0 == strcmp (evt->sip->cseq->method, "ACK")) {#ifdef OSIP_MT smutex_lock (ist_fastmutex);#endif transaction = osip_transaction_find (osip->ist_transactions, evt);#ifdef OSIP_MT smutex_unlock (ist_fastmutex);#endif } else {#ifdef OSIP_MT smutex_lock (nist_fastmutex);#endif transaction = osip_transaction_find (osip->nist_transactions, evt);#ifdef OSIP_MT smutex_unlock (nist_fastmutex);#endif } } else { if (0 == strcmp (evt->sip->cseq->method, "INVITE") || 0 == strcmp (evt->sip->cseq->method, "ACK")) {#ifdef OSIP_MT smutex_lock (ict_fastmutex);#endif transaction = osip_transaction_find (osip->ict_transactions, evt);#ifdef OSIP_MT smutex_unlock (ict_fastmutex);#endif } else {#ifdef OSIP_MT smutex_lock (nict_fastmutex);#endif transaction = osip_transaction_find (osip->nict_transactions, evt);#ifdef OSIP_MT smutex_unlock (nict_fastmutex);#endif } } if (transaction == NULL) { if (EVT_IS_RCV_STATUS_1XX (evt) || EVT_IS_RCV_STATUS_2XX (evt) || EVT_IS_RCV_STATUS_3456XX (evt) || EVT_IS_RCV_ACK (evt)) { /* event MUST be ignored! */ /* EXCEPT FOR 2XX THAT MUST BE GIVEN TO THE CORE LAYER!!! */ /* TODO */ OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_WARNING, NULL, "transaction does not yet exist... %x callid:%s\n", evt, evt->sip->call_id->number)); msg_free (evt->sip); sfree (evt->sip); sfree (evt); /* transaction thread will not delete it */ return NULL; } /* we create a new context for this incoming request */ if (0 == strcmp (evt->sip->cseq->method, "INVITE")) ctx_type = IST; else ctx_type = NIST; i = transaction_init (&transaction, ctx_type, osip, evt->sip); if (i == -1) { msg_free (evt->sip); sfree (evt->sip); sfree (evt); /* transaction thread will not delete it */ return NULL; } } evt->transactionid = transaction->transactionid; evt->transactionid = transaction->transactionid; fifo_add (transaction->transactionff, evt); return transaction; } else { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_BUG, NULL, "wrong event type %x\n", evt)); return NULL; }}#endifintosip_find_transaction_and_add_event (osip_t * osip, sipevent_t * evt){ transaction_t *transaction = __osip_find_transaction (osip, evt, 1); if (transaction == NULL) return -1; return 0;}transaction_t *osip_find_transaction (osip_t * osip, sipevent_t * evt){#ifdef OSIP_MT OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_BUG, NULL, "\n\n\n\nYou are using a multithreaded application, but this method is not allowed! Use osip_find_transaction_add_add_event() instead.\n\n\\n"));#endif return __osip_find_transaction (osip, evt, 0);}transaction_t *__osip_find_transaction (osip_t * osip, sipevent_t * evt, int consume){ transaction_t *transaction = NULL; list_t *transactions = NULL;#ifdef OSIP_MT smutex_t *mut = NULL;#endif if (evt == NULL || evt->sip == NULL || evt->sip->cseq == NULL) return NULL; if (EVT_IS_INCOMINGMSG (evt)) { if (MSG_IS_REQUEST (evt->sip)) { if (0 == strcmp (evt->sip->cseq->method, "INVITE") || 0 == strcmp (evt->sip->cseq->method, "ACK")) { transactions = osip->ist_transactions;#ifdef OSIP_MT mut = ist_fastmutex;#endif } else { transactions = osip->nist_transactions;#ifdef OSIP_MT mut = nist_fastmutex;#endif }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -