From 631fffee8a28b1bec5ed1f1d26a20e0135967f99 Mon Sep 17 00:00:00 2001 From: Mamadou DIOP Date: Mon, 17 Aug 2015 01:56:35 +0200 Subject: - --- .../1.0/tinySIP/src/dialogs/tsip_dialog_layer.c | 500 --------------------- 1 file changed, 500 deletions(-) delete mode 100644 branches/1.0/tinySIP/src/dialogs/tsip_dialog_layer.c (limited to 'branches/1.0/tinySIP/src/dialogs/tsip_dialog_layer.c') diff --git a/branches/1.0/tinySIP/src/dialogs/tsip_dialog_layer.c b/branches/1.0/tinySIP/src/dialogs/tsip_dialog_layer.c deleted file mode 100644 index 959f3dd..0000000 --- a/branches/1.0/tinySIP/src/dialogs/tsip_dialog_layer.c +++ /dev/null @@ -1,500 +0,0 @@ -/* -* Copyright (C) 2009-2010 Mamadou Diop. -* -* Contact: Mamadou Diop -* -* This file is part of Open Source Doubango Framework. -* -* DOUBANGO 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 3 of the License, or -* (at your option) any later version. -* -* DOUBANGO 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 DOUBANGO. -* -*/ - -/**@file tsip_dialog_layer.c - * @brief SIP dialog layer. - * - * @author Mamadou Diop - * - * @date Created: Sat Nov 8 16:54:58 2009 mdiop - */ -#include "tinysip/dialogs/tsip_dialog_layer.h" - -#include "tinysip/dialogs/tsip_dialog_invite.h" -#include "tinysip/dialogs/tsip_dialog_message.h" -#include "tinysip/dialogs/tsip_dialog_options.h" -#include "tinysip/dialogs/tsip_dialog_publish.h" -#include "tinysip/dialogs/tsip_dialog_register.h" -#include "tinysip/dialogs/tsip_dialog_subscribe.h" - -#include "tinysip/transactions/tsip_transac_layer.h" -#include "tinysip/transports/tsip_transport_layer.h" - -#include "tsk_debug.h" - -extern tsip_ssession_handle_t *tsip_ssession_create_2(const tsip_stack_t* stack, const struct tsip_message_s* message); - -/*== Predicate function to find dialog by type */ -static int pred_find_dialog_by_type(const tsk_list_item_t *item, const void *type) -{ - if(item && item->data){ - tsip_dialog_t *dialog = item->data; - return (dialog->type - *((tsip_dialog_type_t*)type)); - } - return -1; -} - -/*== Predicate function to find dialog by not type */ -static int pred_find_dialog_by_not_type(const tsk_list_item_t *item, const void *type) -{ - if(item && item->data){ - tsip_dialog_t *dialog = item->data; - if(dialog->type != *((tsip_dialog_type_t*)type)){ - return 0; - } - } - return -1; -} - -tsip_dialog_layer_t* tsip_dialog_layer_create(tsip_stack_t* stack) -{ - return tsk_object_new(tsip_dialog_layer_def_t, stack); -} - -// it's up to the caller to release the returned object -tsip_dialog_t* tsip_dialog_layer_find_by_ss(tsip_dialog_layer_t *self, const tsip_ssession_handle_t *ss) -{ - tsip_dialog_t *ret = 0; - tsip_dialog_t *dialog; - tsk_list_item_t *item; - - tsk_safeobj_lock(self); - - tsk_list_foreach(item, self->dialogs){ - dialog = item->data; - if( tsip_ssession_get_id(dialog->ss) == tsip_ssession_get_id(ss) ){ - ret = dialog; - break; - } - } - - tsk_safeobj_unlock(self); - - return tsk_object_ref(ret); -} - -// it's up to the caller to release the returned object -tsip_dialog_t* tsip_dialog_layer_find(const tsip_dialog_layer_t *self, const char* callid, const char* to_tag, const char* from_tag, tsip_request_type_t type, tsk_bool_t *cid_matched) -{ - tsip_dialog_t *ret = tsk_null; - tsip_dialog_t *dialog; - tsk_list_item_t *item; - - *cid_matched = tsk_false; - - tsk_safeobj_lock(self); - - tsk_list_foreach(item, self->dialogs){ - dialog = item->data; - if(tsk_strequals(dialog->callid, callid)){ - tsk_bool_t is_cancel = (type == tsip_CANCEL); // Incoming CANCEL - tsk_bool_t is_register = (type == tsip_REGISTER); // Incoming REGISTER - *cid_matched = tsk_true; - /* CANCEL Request will have the same local tag than the INVITE request -> do not compare tags */ - if((is_cancel || tsk_strequals(dialog->tag_local, from_tag)) && tsk_strequals(dialog->tag_remote, to_tag)){ - ret = tsk_object_ref(dialog); - break; - } - /* REGISTER is dialogless which means that each reREGISTER or unREGISTER will have empty to tag */ - if(is_register /* Do not check tags */){ - ret = tsk_object_ref(dialog); - break; - } - } - } - - tsk_safeobj_unlock(self); - - return ret; -} - -/** Hangup all dialogs staring by REGISTER */ -int tsip_dialog_layer_shutdownAll(tsip_dialog_layer_t *self) -{ - if(self){ - tsk_bool_t wait = tsk_false; - tsk_list_item_t *item; - tsip_dialog_t *dialog; - tsip_dialog_type_t regtype = tsip_dialog_REGISTER; - - if(!self->shutdown.inprogress){ - self->shutdown.inprogress = tsk_true; - self->shutdown.condwait = tsk_condwait_create(); - } - - tsk_safeobj_lock(self); - if(tsk_list_count(self->dialogs, pred_find_dialog_by_not_type, ®type)){ - /* There are non-register dialogs ==> phase-1 */ - goto phase1; - } - else if(tsk_list_count(self->dialogs, pred_find_dialog_by_type, ®type)){ - /* There are one or more register dialogs ==> phase-2 */ - goto phase2; - } - else{ - tsk_safeobj_unlock(self); - goto done; - } - -phase1: - /* Phase 1 - shutdown all except register and silent_hangup */ - TSK_DEBUG_INFO("== Shutting down - Phase-1 started =="); -phase1_loop: - tsk_list_foreach(item, self->dialogs){ - dialog = item->data; - if(dialog->type != tsip_dialog_REGISTER && !dialog->ss->silent_hangup){ - item = tsk_object_ref(item); - if(!tsip_dialog_shutdown(dialog, tsk_null)){ - wait = tsk_true; - } - - // if "tsip_dialog_shutdown()" remove the dialog, then - // "self->dialogs" will be unsafe - if(!(item = tsk_object_unref(item))){ - goto phase1_loop; - } - } - } - tsk_safeobj_unlock(self); - - /* wait until phase-1 is completed */ - if(wait){ - tsk_condwait_timedwait(self->shutdown.condwait, TSIP_DIALOG_SHUTDOWN_TIMEOUT); - } - - /* lock and goto phase2 */ - tsk_safeobj_lock(self); - wait = tsk_false; - goto phase2; - -phase2: - /* Phase 2 - unregister */ - TSK_DEBUG_INFO("== Shutting down - Phase-2 started =="); - self->shutdown.phase2 = tsk_true; -phase2_loop: - tsk_list_foreach(item, self->dialogs){ - dialog = item->data; - if(dialog->type == tsip_dialog_REGISTER){ - item = tsk_object_ref(item); - if(!tsip_dialog_shutdown(dialog, tsk_null)){ - wait = tsk_true; - } - // if "tsip_dialog_shutdown()" remove the dialog, then - // "self->dialogs" will be unsafe - if(!(item = tsk_object_unref(item))){ - goto phase2_loop; - } - } - } - tsk_safeobj_unlock(self); - - /* wait until phase-2 is completed */ - if(wait){ - tsk_condwait_timedwait(self->shutdown.condwait, TSIP_DIALOG_SHUTDOWN_TIMEOUT); - } - - - /* Phase 3 - silenthangup (dialogs will be terminated immediately) */ - TSK_DEBUG_INFO("== Shutting down - Phase-3 =="); -phase3_loop: - tsk_list_foreach(item, self->dialogs){ - dialog = item->data; - if(dialog->ss->silent_hangup){ - item = tsk_object_ref(item); - tsip_dialog_shutdown(dialog, tsk_null); - - // if "tsip_dialog_shutdown()" remove the dialog, then - // "self->dialogs" will be unsafe - if(!(item = tsk_object_unref(item))){ - goto phase3_loop; - } - } - } - -done: - return 0; - } - return -1; -} - -/* the caller of this function must unref() the returned object */ -tsip_dialog_t* tsip_dialog_layer_new(tsip_dialog_layer_t *self, tsip_dialog_type_t type, const tsip_ssession_t *ss) -{ - tsip_dialog_t* ret = tsk_null; - tsip_dialog_t* dialog; - if(!self){ - goto bail; - } - - switch(type){ - case tsip_dialog_INVITE: - { - if((dialog = (tsip_dialog_t*)tsip_dialog_invite_create(ss, tsk_null))){ - ret = tsk_object_ref(dialog); - tsk_list_push_back_data(self->dialogs, (void**)&dialog); - } - break; - } - case tsip_dialog_MESSAGE: - { - if((dialog = (tsip_dialog_t*)tsip_dialog_message_create(ss))){ - ret = tsk_object_ref(dialog); - tsk_list_push_back_data(self->dialogs, (void**)&dialog); - } - break; - } - case tsip_dialog_OPTIONS: - { - if((dialog = (tsip_dialog_t*)tsip_dialog_options_create(ss))){ - ret = tsk_object_ref(dialog); - tsk_list_push_back_data(self->dialogs, (void**)&dialog); - } - break; - } - case tsip_dialog_PUBLISH: - { - if((dialog = (tsip_dialog_t*)tsip_dialog_publish_create(ss))){ - ret = tsk_object_ref(dialog); - tsk_list_push_back_data(self->dialogs, (void**)&dialog); - } - break; - } - case tsip_dialog_REGISTER: - { - if((dialog = (tsip_dialog_t*)tsip_dialog_register_create(ss, tsk_null))){ - ret = tsk_object_ref(dialog); - tsk_list_push_back_data(self->dialogs, (void**)&dialog); - } - break; - } - case tsip_dialog_SUBSCRIBE: - { - if((dialog = (tsip_dialog_t*)tsip_dialog_subscribe_create(ss))){ - ret = tsk_object_ref(dialog); - tsk_list_push_back_data(self->dialogs, (void**)&dialog); - } - break; - } - - default: - { - TSK_DEBUG_ERROR("Dialog type not supported."); - break; - } - } - -bail: - return ret; -} - -int tsip_dialog_layer_remove(tsip_dialog_layer_t *self, const tsip_dialog_t *dialog) -{ - if(dialog && self){ - tsip_dialog_type_t regtype = tsip_dialog_REGISTER; - tsk_safeobj_lock(self); - - /* remove the dialog */ - tsk_list_remove_item_by_data(self->dialogs, dialog); - - /* whether shutting down? */ - if(self->shutdown.inprogress){ - if(self->shutdown.phase2){ /* Phase 2 (all non-REGISTER and silent dialogs have been removed) */ - if(tsk_list_count(self->dialogs, pred_find_dialog_by_type, ®type) == 0){ - /* alert only if there is not REGISTER dialog (ignore silents) */ - TSK_DEBUG_INFO("== Shutting down - Phase-2 completed =="); - tsk_condwait_broadcast(self->shutdown.condwait); - } - } - else{ /* Phase 1 */ - if(tsk_list_count(self->dialogs, pred_find_dialog_by_not_type, ®type) == 0){ - /* alert only if all dialogs except REGISTER have been removed */ - TSK_DEBUG_INFO("== Shutting down - Phase-1 completed =="); - tsk_condwait_broadcast(self->shutdown.condwait); - } - } - } - - tsk_safeobj_unlock(self); - - return 0; - } - - return -1; -} - -int tsip_dialog_layer_handle_incoming_msg(const tsip_dialog_layer_t *self, const tsip_message_t* message) -{ - int ret = -1; - tsk_bool_t cid_matched; - tsip_dialog_t* dialog; - tsip_transac_t* transac = tsk_null; - const tsip_transac_layer_t *layer_transac = self->stack->layer_transac; - - if(!layer_transac){ - goto bail; - } - - //tsk_safeobj_lock(self); - dialog = tsip_dialog_layer_find(self, message->Call_ID->value, - TSIP_MESSAGE_IS_RESPONSE(message) ? message->To->tag : message->From->tag, - TSIP_MESSAGE_IS_RESPONSE(message) ? message->From->tag : message->To->tag, - TSIP_MESSAGE_IS_REQUEST(message) ? TSIP_MESSAGE_AS_REQUEST(message)->line.request.request_type : tsip_NONE, - &cid_matched); - //tsk_safeobj_unlock(self); - - if(dialog){ - if(TSIP_REQUEST_IS_CANCEL(message) || TSIP_REQUEST_IS_ACK(message)){ - ret = dialog->callback(dialog, tsip_dialog_i_msg, message); - tsk_object_unref(dialog); - goto bail; - } - else{ - transac = tsip_transac_layer_new(layer_transac, tsk_false, message, TSIP_DIALOG(dialog)); - tsk_object_unref(dialog); - } - } - else{ - if(TSIP_MESSAGE_IS_REQUEST(message)){ - tsip_ssession_t* ss = tsk_null; - tsip_dialog_t* newdialog = tsk_null; - - switch(message->line.request.request_type){ - case tsip_MESSAGE: - { /* Server incoming MESSAGE */ - if((ss = tsip_ssession_create_2(self->stack, message))){ - newdialog = (tsip_dialog_t*)tsip_dialog_message_create(ss); - } - break; - } - - case tsip_REGISTER: - { /* incoming REGISTER */ - if((ss = tsip_ssession_create_2(self->stack, message))){ - newdialog = (tsip_dialog_t*)tsip_dialog_register_create(ss, message->Call_ID ? message->Call_ID->value : tsk_null); - } - break; - } - - case tsip_INVITE: - { /* incoming INVITE */ - if((ss = tsip_ssession_create_2(self->stack, message))){ - newdialog = (tsip_dialog_t*)tsip_dialog_invite_create(ss, message->Call_ID ? message->Call_ID->value : tsk_null); - } - break; - } - - default: - { - break; - } - }//switch - - if(newdialog){ - transac = tsip_transac_layer_new(layer_transac, tsk_false, message, newdialog); - tsk_list_push_back_data(self->dialogs, (void**)&newdialog); /* add new dialog to the layer */ - } - - /* The dialog will become the owner of the SIP session - * => when destoyed => SIP session will be destroyed, unless the user-end takes ownership() */ - TSK_OBJECT_SAFE_FREE(ss); - } - } - - if(transac){ - ret = tsip_transac_start(transac, message); - tsk_object_unref(transac); - } - else if(TSIP_MESSAGE_IS_REQUEST(message)){ /* No transaction match for the SIP request */ - const tsip_transport_layer_t *layer; - tsip_response_t* response = tsk_null; - - if((layer = self->stack->layer_transport)){ - if(cid_matched){ /* We are receiving our own message. */ - response = tsip_response_new(482, "Loop Detected (Check your iFCs)", message); - if(response && !response->To->tag){/* Early dialog? */ - response->To->tag = tsk_strdup("doubango"); - } - } - else{ - response = tsip_response_new(481, "Dialog/Transaction Does Not Exist", message); - } - if(response){ - ret = tsip_transport_layer_send(layer, response->firstVia ? response->firstVia->branch : "no-branch", response); - TSK_OBJECT_SAFE_FREE(response); - } - } - } - -bail: - return ret; -} - - - - - -//======================================================== -// Dialog layer object definition -// -static tsk_object_t* tsip_dialog_layer_ctor(tsk_object_t * self, va_list * app) -{ - tsip_dialog_layer_t *layer = self; - if(layer){ - layer->stack = va_arg(*app, const tsip_stack_t *); - layer->dialogs = tsk_list_create(); - - tsk_safeobj_init(layer); - } - return self; -} - -static tsk_object_t* tsip_dialog_layer_dtor(tsk_object_t * self) -{ - tsip_dialog_layer_t *layer = self; - if(layer){ - TSK_OBJECT_SAFE_FREE(layer->dialogs); - - /* condwait */ - if(layer->shutdown.condwait){ - tsk_condwait_destroy(&layer->shutdown.condwait); - } - - tsk_safeobj_deinit(layer); - - TSK_DEBUG_INFO("*** Dialog Layer destroyed ***"); - } - return self; -} - -static int tsip_dialog_layer_cmp(const tsk_object_t *obj1, const tsk_object_t *obj2) -{ - return -1; -} - -static const tsk_object_def_t tsip_dialog_layer_def_s = -{ - sizeof(tsip_dialog_layer_t), - tsip_dialog_layer_ctor, - tsip_dialog_layer_dtor, - tsip_dialog_layer_cmp, -}; -const tsk_object_def_t *tsip_dialog_layer_def_t = &tsip_dialog_layer_def_s; -- cgit v1.1