Commit fc3d286f authored by Pekka Pessi's avatar Pekka Pessi

Adding soa_asynch.c

darcs-hash:20050908134030-65a35-1f8f82cf3935681c95d0a195730463b2e1351583.gz
parent b460e53c
/*
* This file is part of the Sofia-SIP package
*
* Copyright (C) 2005 Nokia Corporation.
*
* Contact: Pekka Pessi <pekka.pessi@nokia.com>
*
* 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
*
*/
/**@CFILE soa_asynch.c
*
* @brief Static implementation of Sofia SDP Offer/Answer Engine
*
* @author Pekka Pessi <Pekka.Pessi@nokia.com>
*
* @date Created: Tue Aug 16 17:06:06 EEST 2005
* $Date: 2005/08/17 14:51:23 $
*/
#include "config.h"
const char soa_asynch_c_id[] =
"$Id: soa_asynch.c,v 1.1 2005/08/17 14:51:23 ppessi Exp $";
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
struct soa_asynch_complete;
#define SU_MSG_ARG_T struct soa_asynch_completed
#include <su_wait.h>
#include <su_tag_class.h>
#include <su_tag_class.h>
#include <su_tagarg.h>
#include <su_strlst.h>
#include "soa.h"
#include <sdp.h>
#include "soa_session.h"
#define NONE ((void *)-1)
#define XXX assert(!"implemented")
typedef struct soa_asynch_session
{
soa_session_t sss_session[1];
}
soa_asynch_session_t;
struct soa_asynch_completed
{
soa_session_t *completed_session;
unsigned completed_terminated;
};
static int soa_asynch_init(char const *, soa_session_t *, soa_session_t *);
static void soa_asynch_deinit(soa_session_t *);
static int soa_asynch_set_params(soa_session_t *ss, tagi_t const *tags);
static int soa_asynch_get_params(soa_session_t const *ss, tagi_t *tags);
static tagi_t *soa_asynch_get_paramlist(soa_session_t const *ss);
static int soa_asynch_generate_offer(soa_session_t *ss,
soa_callback_f *completed);
static int soa_asynch_generate_answer(soa_session_t *ss,
soa_callback_f *completed);
static void soa_asynch_activate(soa_session_t *ss, char const *option);
static void soa_asynch_terminate(soa_session_t *ss, char const *option);
struct soa_session_actions const soa_asynch_actions =
{
(sizeof soa_asynch_actions),
sizeof (struct soa_asynch_session),
soa_asynch_init,
soa_asynch_deinit,
soa_asynch_set_params,
soa_asynch_get_params,
soa_asynch_get_paramlist,
soa_base_media_features,
soa_base_sip_required,
soa_base_sip_support,
soa_base_remote_sip_features,
soa_base_config_sdp,
soa_asynch_generate_offer,
soa_asynch_generate_answer,
soa_asynch_activate,
soa_asynch_terminate
};
/* Initialize session */
static int soa_asynch_init(char const *name,
soa_session_t *ss,
soa_session_t *parent)
{
soa_asynch_session_t *myss = (void *)ss;
return soa_base_init(name, ss, parent);
}
static void soa_asynch_deinit(soa_session_t *ss)
{
soa_base_deinit(ss);
}
static int soa_asynch_set_params(soa_session_t *ss, tagi_t const *tags)
{
return soa_base_set_params(ss, tags);
}
static int soa_asynch_get_params(soa_session_t const *ss, tagi_t *tags)
{
return soa_base_get_params(ss, tags);
}
static tagi_t *soa_asynch_get_paramlist(soa_session_t const *ss)
{
return soa_base_get_paramlist(ss);
}
static void soa_asynch_completed(su_root_magic_t *magic,
su_msg_r msg,
struct soa_asynch_completed *arg)
{
soa_session_t *ss = arg->completed_session;
if (arg->completed_terminated == ss->ss_terminated) {
if (ss->ss_in_progress) {
soa_callback_f *completed = ss->ss_in_progress;
ss->ss_in_progress = NULL;
/* Update local activity */
if (ss->ss_local)
soa_set_activity(ss, ss->ss_local->sdp_media, 0);
completed(ss->ss_magic, ss);
}
}
soa_session_unref(ss);
}
static int soa_asynch_generate_offer(soa_session_t *ss,
soa_callback_f *completed)
{
sdp_media_t *m;
uint16_t port = 5004;
su_msg_r msg;
if (ss->ss_local == NULL) {
if (ss->ss_caps == NULL)
return soa_set_status(ss, 500, "No local session available");
}
if (ss->ss_local)
return 0; /* We are done */
/* Generate a dummy offer based on our capabilities */
ss->ss_local = sdp_session_dup(ss->ss_home, ss->ss_caps);
if (!ss->ss_local) {
return soa_set_status(ss, 500, "Internal error");
}
for (m = ss->ss_local->sdp_media; m; m = m->m_next)
if (m->m_port == 0)
m->m_port = port, port += 2;
/* We pretend to be asynchronous */
if (su_msg_create(msg,
su_root_task(ss->ss_root),
su_root_task(ss->ss_root),
soa_asynch_completed,
sizeof (struct soa_asynch_completed)) == -1)
return soa_set_status(ss, 500, "Internal error");
su_msg_data(msg)->completed_session = soa_session_ref(ss);
su_msg_data(msg)->completed_terminated = ss->ss_terminated;
su_msg_send(msg);
ss->ss_in_progress = completed;
return 1; /* Indicate caller of async operation */
}
static int soa_asynch_generate_answer(soa_session_t *ss,
soa_callback_f *completed)
{
sdp_media_t *m;
uint16_t port = 5004;
su_msg_r msg;
if (ss->ss_local == NULL) {
if (ss->ss_caps == NULL)
return soa_set_status(ss, 500, "No local session available");
}
if (ss->ss_local)
return 0; /* We are done */
/* Generate a dummy answer based on our capabilities */
ss->ss_local = sdp_session_dup(ss->ss_home, ss->ss_caps);
if (!ss->ss_local) {
return soa_set_status(ss, 500, "Internal error");
}
for (m = ss->ss_local->sdp_media; m; m = m->m_next)
if (m->m_port == 0)
m->m_port = port, port += 2;
/* We pretend to be asynchronous */
if (su_msg_create(msg,
su_root_task(ss->ss_root),
su_root_task(ss->ss_root),
soa_asynch_completed,
sizeof (struct soa_asynch_completed)) == -1)
return soa_set_status(ss, 500, "Internal error");
su_msg_data(msg)->completed_session = soa_session_ref(ss);
su_msg_data(msg)->completed_terminated = ss->ss_terminated;
su_msg_send(msg);
ss->ss_in_progress = completed;
return 1; /* Indicate caller of async operation */
}
static void soa_asynch_activate(soa_session_t *ss, char const *option)
{
soa_base_activate(ss, option);
}
static void soa_asynch_terminate(soa_session_t *ss, char const *option)
{
if (ss->ss_local)
su_free(ss->ss_home, ss->ss_local), ss->ss_local = NULL;
ss->ss_in_progress = NULL;
soa_base_terminate(ss, option);
}
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