udp.c
来自「libosip2-3版本的osip源代码」· C语言 代码 · 共 1,949 行 · 第 1/5 页
C
1,949 行
/* eXosip - This is the eXtended osip library. Copyright (C) 2002, 2003 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_info (eXosip_call_t * jc, eXosip_dialog_t * jd, osip_transaction_t * transaction, osip_event_t * evt);static void eXosip_process_options (eXosip_call_t * jc, eXosip_dialog_t * jd, osip_transaction_t * transaction, osip_event_t * evt);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_refer (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 osip_event_t *eXosip_process_reinvite (eXosip_call_t * jc, eXosip_dialog_t * jd, osip_transaction_t * transaction, osip_event_t * evt);static void eXosip_process_new_options (osip_transaction_t * transaction, osip_event_t * evt);static void eXosip_process_new_invite (osip_transaction_t * transaction, osip_event_t * evt);static 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);static void eXosip_process_message_outside_of_dialog (osip_transaction_t * tr, osip_event_t * evt);static void eXosip_process_refer_outside_of_dialog (osip_transaction_t * tr, osip_event_t * evt);static 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);static int eXosip_release_finished_transactions_for_subscription (eXosip_dialog_t *jd);static 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_options (eXosip_call_t * jc, eXosip_dialog_t * jd, osip_transaction_t * transaction, osip_event_t * evt){ osip_list_add (jd->d_inc_trs, transaction, 0); osip_transaction_set_your_instance (transaction, __eXosip_new_jinfo (jc, jd, NULL, NULL)); __eXosip_wakeup ();}static voideXosip_process_info (eXosip_call_t * jc, eXosip_dialog_t * jd, osip_transaction_t * transaction, osip_event_t * evt){ osip_list_add (jd->d_inc_trs, transaction, 0); osip_transaction_set_your_instance (transaction, __eXosip_new_jinfo (jc, jd, NULL, NULL)); __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; osip_transaction_set_your_instance (transaction, __eXosip_new_jinfo (jc, NULL /*jd */ , NULL, NULL)); 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_refer (eXosip_call_t * jc, eXosip_dialog_t * jd, osip_transaction_t * transaction, osip_event_t * evt){ osip_header_t *referto_head = NULL; osip_contact_t *referto; int i; /* check if the refer is valid */ osip_message_header_get_byname (evt->sip, "refer-to", 0, &referto_head); if (referto_head == NULL || referto_head->hvalue == NULL) { osip_list_add (eXosip.j_transactions, transaction, 0); eXosip_send_default_answer (jd, transaction, evt, 400, "Missing Refer-To header", "Missing Refer-To header", __LINE__); return; } /* check if refer-to is well-formed */ osip_contact_init (&referto); i = osip_contact_parse (referto, referto_head->hvalue); if (i != 0) { osip_contact_free (referto); osip_list_add (eXosip.j_transactions, transaction, 0); eXosip_send_default_answer (jd, transaction, evt, 400, "Non valid Refer-To header", "Non valid Refer-To header", __LINE__); return; } osip_contact_free (referto); /* check policy so we can decline immediatly the refer */ osip_transaction_set_your_instance (transaction, __eXosip_new_jinfo (jc, jd, NULL, NULL)); osip_list_add (jd->d_inc_trs, transaction, 0); __eXosip_wakeup ();}static voideXosip_process_notify_for_refer (eXosip_call_t * jc, eXosip_dialog_t * jd, osip_transaction_t * transaction, osip_event_t * evt){#if 0 osip_event_t *evt_answer; osip_message_t *answer; int i; osip_transaction_t *ref; osip_header_t *event_hdr; osip_header_t *sub_state; osip_content_type_t *ctype; osip_body_t *body = NULL; /* get the event type and return "489 Bad Event". */ osip_message_header_get_byname (evt->sip, "event", 0, &event_hdr); if (event_hdr == NULL || event_hdr->hvalue == NULL) { osip_list_add (eXosip.j_transactions, transaction, 0); eXosip_send_default_answer (jd, transaction, evt, 400, "Missing Event header in Notify", "Missing Event header in Notify", __LINE__); return; } if (NULL == strstr (event_hdr->hvalue, "refer")) { osip_list_add (eXosip.j_transactions, transaction, 0); eXosip_send_default_answer (jd, transaction, evt, 501, "Unsupported Event header", "Unsupported Event header in Notify", __LINE__); return; } osip_message_header_get_byname (evt->sip, "subscription-state", 0, &sub_state); if (sub_state == NULL || sub_state->hvalue == NULL) {#ifndef CISCO_BUG osip_list_add (eXosip.j_transactions, transaction, 0); eXosip_send_default_answer (jd, transaction, evt, 400, "Missing Header", "Missing subscription-state Header", __LINE__); return;#else OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_WARNING, NULL, "eXosip: Missing subscription-state Header (cisco 7960 bug)\n"));#endif } ctype = osip_message_get_content_type (evt->sip); if (ctype == NULL || ctype->type == NULL || ctype->subtype == NULL) { osip_list_add (eXosip.j_transactions, transaction, 0); eXosip_send_default_answer (jd, transaction, evt, 400, "Missing Header", "Missing Content-Type Header", __LINE__); return; } if (0 != osip_strcasecmp (ctype->type, "message") || 0 != osip_strcasecmp (ctype->subtype, "sipfrag")) { osip_list_add (eXosip.j_transactions, transaction, 0); eXosip_send_default_answer (jd, transaction, evt, 501, "Unsupported body type", "Unsupported body type", __LINE__); return; } osip_message_get_body (evt->sip, 0, &body); if (body == NULL || body->body == NULL) { osip_list_add (eXosip.j_transactions, transaction, 0); eXosip_send_default_answer (jd, transaction, evt, 400, "Missing Body", "Missing Body", __LINE__); return; }#if 0 report_call_event (EXOSIP_CALL_REFER_STATUS, jc, jd, transaction);#endif /* check if a refer was sent previously! */ ref = eXosip_find_last_out_transaction (jc, jd, "REFER"); if (ref == NULL) { osip_list_add (eXosip.j_transactions, transaction, 0); eXosip_send_default_answer (jd, transaction, evt, 481, NULL, "No associated refer", __LINE__); return; } osip_transaction_set_your_instance (transaction, __eXosip_new_jinfo (jc, jd, NULL, NULL)); /* for now, send default response of 200ok. eventually, application should be deciding how to answer NOTIFY messages */ i = _eXosip_build_response_default (&answer, jd->d_dialog, 200, evt->sip); if (i != 0) { osip_list_add (eXosip.j_transactions, transaction, 0); return; } i = complete_answer_that_establish_a_dialog (answer, evt->sip); 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 ();#else osip_list_add (jd->d_inc_trs, transaction, 0); osip_transaction_set_your_instance (transaction, __eXosip_new_jinfo (jc, jd, NULL, NULL)); __eXosip_wakeup ();#endif}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; /* stop ACK retransmission, in case there is any */ jd->d_count=0; osip_message_free(jd->d_200Ok); jd->d_200Ok=NULL;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?