Commit a0b9f904 authored by Kai Vehmanen's avatar Kai Vehmanen

Added missing nua_glib_op.c file.

darcs-hash:20060913210254-7659e-d463b901c4201b7a697388c5d94f0e7925e96f0b.gz
parent f0c1f0bb
/*
* This file is part of the Sofia-SIP package
*
* Copyright (C) 2005-2006 Nokia Corporation.
* Contact: Pekka Pessi <pekka.pessi@nokia.com>
*
* Copyright (C) 2005 Collabora Ltd.
*
* 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., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*
*/
/**@file nua_glib.c Interface towards libsofia-sip-ua.
*
* @author Kai Vehmanen <kai.vehmanen@nokia.com>
* @author Rob Taylor <rob.taylor@collabora.co.uk>
* @author Pekka Pessi <pekka.pessi@nokia.com>
*/
#include <sofia-sip/nua_glib.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include "nua_glib_priv.h"
#include "nua_glib_op.h"
static void priv_oper_assign(NuaGlibOp *op, sip_method_t method);
/**
* Creates a new operation object and stores it the list of
* active operations for 'self'.
*/
NuaGlibOp *nua_glib_op_create(NuaGlib *self,
sip_method_t method,
const char *address,
tag_type_t tag, tag_value_t value, ...)
{
NuaGlibOp *op, *old;
const char* method_name = sip_method_name(method, "<NONE>");
ta_list ta;
enter;
for (old = self->priv->operations; old; old = old->op_next)
if (!old->op_persistent)
break;
if (address) {
int have_url = 1;
sip_to_t *to;
to = sip_to_make(self->priv->home, address);
if (to == NULL) {
/*TODO, error returns*/
g_warning("%s: %s: invalid address: %s\n", self->priv->name, method_name, address);
return NULL;
}
/* Try to make sense out of the URL */
if (url_sanitize(to->a_url) < 0) {
/*TODO, error returns*/
g_warning("%s: %s: invalid address\n", self->priv->name, method_name);
return NULL;
}
if (!(op = su_zalloc(self->priv->home, sizeof(*op)))) {
/*TODO, error returns*/
g_warning("%s: %s: cannot create handle\n", self->priv->name, method_name);
return NULL;
}
op->op_parent = self;
op->op_next = self->priv->operations;
op->op_prev_state = -1;
self->priv->operations = op;
if (method == sip_method_register)
have_url = 0;
ta_start(ta, tag, value);
op->op_handle = nua_handle(self->priv->nua, op,
TAG_IF(have_url, NUTAG_URL(to->a_url)),
SIPTAG_TO(to),
ta_tags(ta));
ta_end(ta);
op->op_ident = sip_header_as_string(self->priv->home, (sip_header_t *)to);
priv_oper_assign(op, method);
if (!op->op_persistent) {
NuaGlibOp *old_next;
for (; old; old = old_next) { /* Clean old handles */
old_next = old->op_next;
if (!old->op_persistent && !old->op_callstate)
nua_glib_op_destroy(self, old);
}
}
su_free(self->priv->home, to);
}
else if (method)
priv_oper_assign(op = old, method);
else
return old;
if (!op) {
if (address)
/*TODO, error returns*/
g_warning("%s: %s: invalid destination\n", self->priv->name, method_name);
else
/*TODO, error returns*/
g_warning("%s: %s: no destination\n", self->priv->name, method_name);
return NULL;
}
return op;
}
/**
* Creates an operation handle and binds it to an existing handle
* 'nh' (does not create a new nua handle with nua_handle()).
*/
NuaGlibOp *nua_glib_op_create_with_handle(NuaGlib *self,
sip_method_t method,
nua_handle_t *nh,
sip_from_t const *from)
{
NuaGlibOp *op;
enter;
if ((op = su_zalloc(self->priv->home, sizeof(*op)))) {
op->op_parent = self;
op->op_next = self->priv->operations;
self->priv->operations = op;
priv_oper_assign(op, method);
nua_handle_bind(op->op_handle = nh, op);
op->op_ident = sip_header_as_string(self->priv->home, (sip_header_t*)from);
}
else {
SU_DEBUG_1(("%s: cannot create operation object for method=%d\n",
self->priv->name, (int)method));
}
return op;
}
/** Delete operation and attached handles and identities */
void nua_glib_op_destroy(NuaGlib *self, NuaGlibOp *op)
{
NuaGlibOp **prev;
if (!op)
return;
g_assert(op->data == NULL);
/* Remove from queue */
for (prev = &self->priv->operations;
*prev && *prev != op;
prev = &(*prev)->op_next)
;
if (*prev)
*prev = op->op_next, op->op_next = NULL;
if (op->op_authlist)
nua_glib_auth_clear(self, op);
if (op->op_handle)
nua_handle_destroy(op->op_handle), op->op_handle = NULL;
su_free(self->priv->home, op);
}
/**
* Finds a call/session operation (an operation that has non-zero
* op_callstate).
*/
NuaGlibOp *nua_glib_op_find_session(NuaGlib *self)
{
NuaGlibOp *op;
for (op = self->priv->operations; op; op = op->op_next)
if (op->op_callstate)
break;
return op;
}
/**
* Checks whether 'op' is a valid handle or not.
*
* @return op if valid, NULL otherwise
*/
NuaGlibOp *nua_glib_op_check(NuaGlib *self, NuaGlibOp *op)
{
NuaGlibOp *tmp;
for (tmp = self->priv->operations; tmp; tmp = tmp->op_next)
if (tmp == op)
return op;
return NULL;
}
/* ======================================================================
* static functions
* ====================================================================== */
static void
priv_oper_assign(NuaGlibOp *op, sip_method_t method)
{
if (!op)
return;
op->op_method = method;
op->op_persistent =
method == sip_method_subscribe ||
method == sip_method_register ||
method == sip_method_publish;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment