/*
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>
#endif
extern 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 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)
{
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 void
eXosip_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 void
eXosip_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 void
eXosip_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;