📄 udp.c
字号:
/* eXosip - This is the eXtended osip library. Copyright (C) 2002,2003,2004,2005,2006,2007 Aymeric MOIZARD - jack@atosc.org eXosip 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 2 of the License, or (at your option) any later version. eXosip 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 this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*/#ifdef ENABLE_MPATROL#include <mpatrol.h>#endif#include "eXosip2.h"#include <eXosip2/eXosip.h>#ifndef WIN32#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#ifdef __APPLE_CC__#include <unistd.h>#endif#else#include <windows.h>#endifextern eXosip_t eXosip;extern int ipv6_enable;/* Private functions */static void eXosip_send_default_answer (eXosip_dialog_t * jd, osip_transaction_t * transaction, osip_event_t * evt, int status, char *reason_phrase, char *warning, int line);static void eXosip_process_bye (eXosip_call_t * jc, eXosip_dialog_t * jd, osip_transaction_t * transaction, osip_event_t * evt);static void eXosip_process_ack (eXosip_call_t * jc, eXosip_dialog_t * jd, osip_event_t * evt);static void eXosip_process_prack (eXosip_call_t * jc, eXosip_dialog_t * jd, osip_transaction_t * transaction, osip_event_t * evt);static int cancel_match_invite (osip_transaction_t * invite, osip_message_t * cancel);static void eXosip_process_cancel (osip_transaction_t * transaction, osip_event_t * evt);static void eXosip_process_reinvite (eXosip_call_t * jc, eXosip_dialog_t * jd, osip_transaction_t * transaction, osip_event_t * evt);static void eXosip_process_new_invite (osip_transaction_t * transaction, osip_event_t * evt);#ifndef MINISIZEstatic void eXosip_process_new_subscribe (osip_transaction_t * transaction, osip_event_t * evt);static void eXosip_process_subscribe_within_call (eXosip_notify_t * jn, eXosip_dialog_t * jd, osip_transaction_t * transaction, osip_event_t * evt);static void eXosip_process_notify_within_dialog (eXosip_subscribe_t * js, eXosip_dialog_t * jd, osip_transaction_t * transaction, osip_event_t * evt);static int eXosip_match_notify_for_subscribe (eXosip_subscribe_t * js, osip_message_t * notify);#endifstatic void eXosip_process_message_within_dialog (eXosip_call_t * jc, eXosip_dialog_t * jd, osip_transaction_t * transaction, osip_event_t * evt);static void eXosip_process_newrequest (osip_event_t * evt, int socket);static void eXosip_process_response_out_of_transaction (osip_event_t * evt);static int eXosip_pendingosip_transaction_exist (eXosip_call_t * jc, eXosip_dialog_t * jd);static int eXosip_release_finished_calls (eXosip_call_t * jc, eXosip_dialog_t * jd);static int eXosip_release_aborted_calls (eXosip_call_t * jc, eXosip_dialog_t * jd);static int eXosip_release_finished_transactions (eXosip_call_t * jc, eXosip_dialog_t * jd);#ifndef MINISIZEstatic int eXosip_release_finished_transactions_for_subscription (eXosip_dialog_t * jd);#endifstatic voideXosip_send_default_answer (eXosip_dialog_t * jd, osip_transaction_t * transaction, osip_event_t * evt, int status, char *reason_phrase, char *warning, int line){ osip_event_t *evt_answer; osip_message_t *answer; int i; /* osip_list_add(&eXosip.j_transactions, transaction, 0); */ osip_transaction_set_your_instance (transaction, NULL); /* THIS METHOD DOES NOT ACCEPT STATUS CODE BETWEEN 101 and 299 */ if (status > 100 && status < 299 && MSG_IS_INVITE (evt->sip)) return; if (jd != NULL) i = _eXosip_build_response_default (&answer, jd->d_dialog, status, evt->sip); else i = _eXosip_build_response_default (&answer, NULL, status, evt->sip); if (i != 0 || answer == NULL) { return; } if (reason_phrase != NULL) { char *_reason; _reason = osip_message_get_reason_phrase (answer); if (_reason != NULL) osip_free (_reason); _reason = osip_strdup (reason_phrase); osip_message_set_reason_phrase (answer, _reason); } osip_message_set_content_length (answer, "0"); if (status == 500) osip_message_set_retry_after (answer, "10"); evt_answer = osip_new_outgoing_sipmessage (answer); evt_answer->transactionid = transaction->transactionid; osip_transaction_add_event (transaction, evt_answer); __eXosip_wakeup ();}static voideXosip_process_bye (eXosip_call_t * jc, eXosip_dialog_t * jd, osip_transaction_t * transaction, osip_event_t * evt){ osip_event_t *evt_answer; osip_message_t *answer; int i;#ifndef MINISIZE osip_transaction_set_your_instance (transaction, __eXosip_new_jinfo (jc, NULL /*jd */ , NULL, NULL));#else osip_transaction_set_your_instance (transaction, __eXosip_new_jinfo (jc, NULL /*jd */ ));#endif i = _eXosip_build_response_default (&answer, jd->d_dialog, 200, evt->sip); if (i != 0) { osip_list_add (&eXosip.j_transactions, transaction, 0); return; } osip_message_set_content_length (answer, "0"); evt_answer = osip_new_outgoing_sipmessage (answer); evt_answer->transactionid = transaction->transactionid; osip_list_add (jd->d_inc_trs, transaction, 0); /* Release the eXosip_dialog */ osip_dialog_free (jd->d_dialog); jd->d_dialog = NULL; osip_transaction_add_event (transaction, evt_answer); osip_nist_execute (eXosip.j_osip); report_call_event (EXOSIP_CALL_MESSAGE_NEW, jc, jd, transaction); report_call_event (EXOSIP_CALL_CLOSED, jc, jd, transaction); eXosip_update (); /* AMD 30/09/05 */ __eXosip_wakeup ();}static voideXosip_process_ack (eXosip_call_t * jc, eXosip_dialog_t * jd, osip_event_t * evt){ /* TODO: We should find the matching transaction for this ACK and also add the ACK in the event. */ eXosip_event_t *je; int i; je = eXosip_event_init_for_call (EXOSIP_CALL_ACK, jc, jd, NULL); if (je != NULL) { osip_transaction_t *tr; tr = eXosip_find_last_inc_invite (jc, jd); if (tr != NULL) { je->tid = tr->transactionid; /* fill request and answer */ if (tr->orig_request != NULL) { i = osip_message_clone (tr->orig_request, &je->request); if (i != 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "failed to clone request for event\n")); } } if (tr->last_response != NULL) { i = osip_message_clone (tr->last_response, &je->response); if (i != 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "failed to clone response for event\n")); } } } i = osip_message_clone (evt->sip, &je->ack); if (i != 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "failed to clone ACK for event\n")); } } /* stop ACK retransmission, in case there is any */ jd->d_count = 0; osip_message_free (jd->d_200Ok); jd->d_200Ok = NULL; if (je != NULL) report_event (je, NULL); osip_event_free (evt);}static voideXosip_process_prack (eXosip_call_t * jc, eXosip_dialog_t * jd, osip_transaction_t * transaction, osip_event_t * evt){ osip_event_t *evt_answer; osip_message_t *answer; int i;#ifndef MINISIZE osip_transaction_set_your_instance (transaction, __eXosip_new_jinfo (jc, jd, NULL, NULL));#else osip_transaction_set_your_instance (transaction, __eXosip_new_jinfo (jc, jd));#endif i = _eXosip_build_response_default (&answer, jd->d_dialog, 200, evt->sip); if (i != 0) { osip_list_add (&eXosip.j_transactions, transaction, 0); return; } evt_answer = osip_new_outgoing_sipmessage (answer); evt_answer->transactionid = transaction->transactionid; osip_list_add (jd->d_inc_trs, transaction, 0); osip_transaction_add_event (transaction, evt_answer); __eXosip_wakeup ();}static intcancel_match_invite (osip_transaction_t * invite, osip_message_t * cancel){ osip_generic_param_t *br; osip_generic_param_t *br2; osip_via_t *via; osip_via_param_get_byname (invite->topvia, "branch", &br); via = osip_list_get (&cancel->vias, 0); if (via == NULL) return OSIP_SYNTAXERROR; /* request without via??? */ osip_via_param_get_byname (via, "branch", &br2); if (br != NULL && br2 == NULL) return OSIP_UNDEFINED_ERROR; if (br2 != NULL && br == NULL) return OSIP_UNDEFINED_ERROR; if (br2 != NULL && br != NULL) /* compliant UA :) */ { if (br->gvalue != NULL && br2->gvalue != NULL && 0 == strcmp (br->gvalue, br2->gvalue)) return OSIP_SUCCESS; return OSIP_UNDEFINED_ERROR; } /* old backward compatibility mechanism */ if (0 != osip_call_id_match (invite->callid, cancel->call_id)) return OSIP_UNDEFINED_ERROR; if (0 != osip_to_tag_match (invite->to, cancel->to)) return OSIP_UNDEFINED_ERROR; if (0 != osip_from_tag_match (invite->from, cancel->from)) return OSIP_UNDEFINED_ERROR; if (0 != osip_via_match (invite->topvia, via)) return OSIP_UNDEFINED_ERROR; return OSIP_SUCCESS;}static voideXosip_process_cancel (osip_transaction_t * transaction, osip_event_t * evt){ osip_transaction_t *tr; osip_event_t *evt_answer; osip_message_t *answer; int i; eXosip_call_t *jc; eXosip_dialog_t *jd; tr = NULL; jd = NULL; /* first, look for a Dialog in the map of element */ for (jc = eXosip.j_calls; jc != NULL; jc = jc->next) { if (jc->c_inc_tr != NULL) { i = cancel_match_invite (jc->c_inc_tr, evt->sip); if (i == 0) { tr = jc->c_inc_tr; /* fixed */ if (jc->c_dialogs != NULL) jd = jc->c_dialogs; break; } } tr = NULL; for (jd = jc->c_dialogs; jd != NULL; jd = jd->next) { int pos = 0; while (!osip_list_eol (jd->d_inc_trs, pos)) { tr = osip_list_get (jd->d_inc_trs, pos); i = cancel_match_invite (tr, evt->sip); if (i == 0) break; tr = NULL; pos++; } } if (jd != NULL) break; /* tr has just been found! */ } if (tr == NULL) /* we didn't found the transaction to cancel */ { i = _eXosip_build_response_default (&answer, NULL, 481, evt->sip); if (i != 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: cannot cancel transaction.\n")); osip_list_add (&eXosip.j_transactions, tr, 0); osip_transaction_set_your_instance (tr, NULL); return; } osip_message_set_content_length (answer, "0"); evt_answer = osip_new_outgoing_sipmessage (answer); evt_answer->transactionid = transaction->transactionid; osip_transaction_add_event (transaction, evt_answer); osip_list_add (&eXosip.j_transactions, transaction, 0); osip_transaction_set_your_instance (transaction, NULL); __eXosip_wakeup (); return; } if (tr->state == IST_TERMINATED || tr->state == IST_CONFIRMED || tr->state == IST_COMPLETED)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -