ports/105884: [PATCH] net/linphone-base: fix breakage by libosip2 update
Matus Harvan
m.harvan at iu-bremen.de
Sun Nov 26 20:38:32 UTC 2006
>Number: 105884
>Category: ports
>Synopsis: [PATCH] net/linphone-base: fix breakage by libosip2 update
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: freebsd-ports-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Sun Nov 26 20:20:04 GMT 2006
>Closed-Date:
>Last-Modified:
>Originator: Matus Harvan
>Release: FreeBSD 6.1-RELEASE-p9 i386
>Organization:
International University Bremen
>Environment:
System: FreeBSD twoflower 6.1-RELEASE-p9 FreeBSD 6.1-RELEASE-p9 #0: Fri Nov 3 21:40:44 CET 2006 root at twoflower:/usr/obj/usr/src/sys/TWOFLOWER-SMP i386
>Description:
net/linphone-base was broken by an update to libosip2. The new version of
libosip2, 2.2.3, has removed osip_negotiation, which linphone is using.
>How-To-Repeat:
>Fix:
The attached patch adds 3 files from libosip2 version 2.2.2, where
osip_negotiation is implemented. Minor changes to #include and Makefiles were
needed to build within the linphone source tree.
--- linphone-base.patch begins here ---
diff -ruN linphone-base.orig/files/patch-exosip::Makefile.am linphone-base/files/patch-exosip::Makefile.am
--- linphone-base.orig/files/patch-exosip::Makefile.am Thu Jan 1 01:00:00 1970
+++ linphone-base/files/patch-exosip::Makefile.am Fri Nov 24 18:58:53 2006
@@ -0,0 +1,11 @@
+--- exosip/Makefile.am.orig Sun Nov 19 13:48:46 2006
++++ exosip/Makefile.am Sun Nov 19 13:41:51 2006
+@@ -9,7 +9,7 @@
+ jnotify.c jsubscribers.c jsubscribe.c jevents.c \
+ sdp_offans.c misc.c eXosip2.h \
+ jpipe.c jpipe.h jauth.c jpublish.c \
+-eXosip.h eXosip_cfg.h
++eXosip.h eXosip_cfg.h osip_negotiation.h osip_negotiation.c
+
+ libeXosip_la_LIBADD = $(EXOSIP_LIBS)
+
diff -ruN linphone-base.orig/files/patch-exosip::Makefile.in linphone-base/files/patch-exosip::Makefile.in
--- linphone-base.orig/files/patch-exosip::Makefile.in Thu Jan 1 01:00:00 1970
+++ linphone-base/files/patch-exosip::Makefile.in Fri Nov 24 18:58:53 2006
@@ -0,0 +1,38 @@
+--- exosip/Makefile.in.orig Thu Nov 23 01:03:41 2006
++++ exosip/Makefile.in Thu Nov 23 01:09:15 2006
+@@ -55,7 +55,7 @@
+ jcallback.lo jdialog.lo udp.lo jcall.lo jreg.lo jfreinds.lo \
+ jidentity.lo eXutils.lo jnotify.lo jsubscribers.lo \
+ jsubscribe.lo jevents.lo sdp_offans.lo misc.lo jpipe.lo \
+- jauth.lo jpublish.lo
++ jauth.lo jpublish.lo osip_negotiation.lo
+ libeXosip_la_OBJECTS = $(am_libeXosip_la_OBJECTS)
+ DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
+ depcomp = $(SHELL) $(top_srcdir)/depcomp
+@@ -70,7 +70,8 @@
+ @AMDEP_TRUE@ ./$(DEPDIR)/jresponse.Plo \
+ @AMDEP_TRUE@ ./$(DEPDIR)/jsubscribe.Plo \
+ @AMDEP_TRUE@ ./$(DEPDIR)/jsubscribers.Plo ./$(DEPDIR)/misc.Plo \
+- at AMDEP_TRUE@ ./$(DEPDIR)/sdp_offans.Plo ./$(DEPDIR)/udp.Plo
++ at AMDEP_TRUE@ ./$(DEPDIR)/sdp_offans.Plo ./$(DEPDIR)/udp.Plo \
++ at AMDEP_TRUE@ ./$(DEPDIR)/osip_negotiation.Plo
+ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+ LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) \
+@@ -303,7 +304,7 @@
+ jnotify.c jsubscribers.c jsubscribe.c jevents.c \
+ sdp_offans.c misc.c eXosip2.h \
+ jpipe.c jpipe.h jauth.c jpublish.c \
+-eXosip.h eXosip_cfg.h
++eXosip.h eXosip_cfg.h osip_negotiation.h osip_negotiation.c
+
+ libeXosip_la_LIBADD = $(EXOSIP_LIBS)
+ INCLUDES = -I$(top_srcdir)
+@@ -378,6 +379,7 @@
+ @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/misc.Plo at am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/sdp_offans.Plo at am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/udp.Plo at am__quote@
++ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/osip_negotiation.Plo at am__quote@
+
+ .c.o:
+ @am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
diff -ruN linphone-base.orig/files/patch-exosip::eXosip.h linphone-base/files/patch-exosip::eXosip.h
--- linphone-base.orig/files/patch-exosip::eXosip.h Thu Jan 1 01:00:00 1970
+++ linphone-base/files/patch-exosip::eXosip.h Fri Nov 24 18:58:53 2006
@@ -0,0 +1,11 @@
+--- exosip/eXosip.h.orig Sun Nov 19 13:39:40 2006
++++ exosip/eXosip.h Sun Nov 19 13:39:56 2006
+@@ -26,7 +26,7 @@
+ #define __EXOSIP_H__
+
+ #include <osipparser2/osip_parser.h>
+-#include <osip2/osip_negotiation.h>
++#include "osip_negotiation.h"
+ #include <time.h>
+
+ /**
diff -ruN linphone-base.orig/files/patch-exosip::eXosip2.h linphone-base/files/patch-exosip::eXosip2.h
--- linphone-base.orig/files/patch-exosip::eXosip2.h Thu Jan 1 01:00:00 1970
+++ linphone-base/files/patch-exosip::eXosip2.h Fri Nov 24 18:58:53 2006
@@ -0,0 +1,11 @@
+--- exosip/eXosip2.h.orig Sun Nov 19 14:10:23 2006
++++ exosip/eXosip2.h Sun Nov 19 14:10:42 2006
+@@ -44,7 +44,7 @@
+
+ #include <osip2/osip.h>
+ #include <osip2/osip_dialog.h>
+-#include <osip2/osip_negotiation.h>
++#include "osip_negotiation.h"
+
+ #include <eXosip_cfg.h>
+ #include <eXosip.h>
diff -ruN linphone-base.orig/files/patch-exosip::internal.h linphone-base/files/patch-exosip::internal.h
--- linphone-base.orig/files/patch-exosip::internal.h Thu Jan 1 01:00:00 1970
+++ linphone-base/files/patch-exosip::internal.h Fri Nov 24 19:00:50 2006
@@ -0,0 +1,257 @@
+--- exosip.orig/internal.h Thu Jan 1 01:00:00 1970
++++ exosip/internal.h Sun Nov 19 14:36:21 2006
+@@ -0,0 +1,253 @@
++/*
++ The oSIP library implements the Session Initiation Protocol (SIP -rfc3261-)
++ Copyright (C) 2001,2002,2003,2004 Aymeric MOIZARD jack at atosc.org
++
++ 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++*/
++
++
++#include <osipparser2/osip_port.h>
++
++#ifndef _INTERNAL_H_
++#define _INTERNAL_H_
++
++#ifdef __BORLANDC__
++#define _timeb timeb
++#define _ftime ftime
++#endif
++
++#ifndef DOXYGEN
++
++/**
++ * Structure for payload management. Each payload element
++ * represents one codec of a media line.
++ * @var __payload_t
++ */
++typedef struct __payload __payload_t;
++
++struct __payload
++{
++ char *payload;
++ /* char *port; this must be assigned by the application dynamicly */
++ char *number_of_port;
++ char *proto;
++ char *c_nettype;
++ char *c_addrtype;
++ char *c_addr;
++ char *c_addr_multicast_ttl;
++ char *c_addr_multicast_int;
++ /* rtpmap (rcvonly and other attributes are added dynamicly) */
++ char *a_rtpmap;
++};
++
++
++/**
++ * Allocate a payload element.
++ * @param payload The payload.
++ */
++int __payload_init (__payload_t ** payload);
++
++/**
++ * Free a payload element.
++ * @param payload The payload.
++ */
++void __payload_free (__payload_t * payload);
++
++
++#ifdef OSIP_MT
++
++/* Thread abstraction layer definition */
++
++/* Is there any thread implementation available? */
++/* HAVE_PTHREAD_H is not used any more! I keep it for a while... */
++#if !defined(__VXWORKS_OS__) && !defined(__PSOS__) && \
++ !defined(WIN32) && !defined(_WIN32_WCE) && !defined(HAVE_PTHREAD_WIN32) && \
++ !defined(HAVE_PTHREAD) && !defined(HAVE_PTHREAD_H) && !defined(HAVE_PTH_PTHREAD_H)
++#error No thread implementation found!
++#endif
++
++/* Pthreads support: */
++/* - Unix: native Pthreads. */
++/* - Win32: Pthreads for Win32 (http://sources.redhat.com/pthreads-win32). */
++#if defined(HAVE_PTHREAD) || defined(HAVE_PTHREAD_H) || defined(HAVE_PTH_PTHREAD_H) || \
++ defined(HAVE_PTHREAD_WIN32)
++#include <pthread.h>
++typedef pthread_t osip_thread_t;
++#endif
++
++/* Windows without Pthreads for Win32 */
++#if (defined(WIN32) || defined(_WIN32_WCE)) && !defined(HAVE_PTHREAD_WIN32)
++/* Prevent the inclusion of winsock.h */
++#define _WINSOCKAPI_
++#include <windows.h>
++#undef _WINSOCKAPI_
++typedef struct
++{
++ HANDLE h;
++ unsigned id;
++}
++osip_thread_t;
++#endif
++
++#ifdef __VXWORKS_OS__
++#include <taskLib.h>
++typedef struct
++{
++ int id;
++}
++osip_thread_t;
++#endif
++
++#ifdef __PSOS__
++#include <psos.h>
++typedef struct
++{
++ unsigned long tid;
++}
++osip_thread_t;
++#endif
++
++
++/* Semaphore and Mutex abstraction layer definition */
++
++/* Is there any semaphore implementation available? */
++#if !defined(HAVE_SEMAPHORE_H) && !defined(HAVE_SYS_SEM_H) && \
++ !defined(WIN32) && !defined(_WIN32_WCE) && !defined(HAVE_PTHREAD_WIN32) && \
++ !defined(__PSOS__) && !defined(__VXWORKS_OS__)
++#error No semaphore implementation found
++#endif
++
++/* Pthreads */
++#if defined(HAVE_PTHREAD) || defined(HAVE_PTHREAD_H) || defined(HAVE_PTH_PTHREAD_H) || \
++ defined(HAVE_PTHREAD_WIN32)
++typedef pthread_mutex_t osip_mutex_t;
++#endif
++
++#ifdef __sun__
++#include <semaphore.h>
++#undef getdate
++#include <synch.h>
++#endif
++
++#if (defined(HAVE_SEMAPHORE_H) && !defined(__APPLE_CC__)) || defined(HAVE_PTHREAD_WIN32)
++#include <semaphore.h>
++#ifdef __sun__
++#undef getdate
++#include <synch.h>
++#endif
++/**
++ * Structure for referencing a semaphore element.
++ * @var osip_sem_t
++ */
++typedef sem_t osip_sem_t;
++
++#elif defined(HAVE_SYS_SEM_H)
++#include <sys/types.h>
++#include <sys/ipc.h>
++#include <sys/sem.h>
++typedef struct
++{
++ int semid;
++}
++osip_sem_t;
++#endif
++
++/* Windows without Pthreads for Win32 */
++#if (defined(WIN32) || defined(_WIN32_WCE)) && !defined(HAVE_PTHREAD_WIN32)
++/* Prevent the inclusion of winsock.h */
++#define _WINSOCKAPI_
++#include <windows.h>
++#undef _WINSOCKAPI_
++
++#if (_WIN32_WINNT >= 0x0500)
++
++#define OSIP_CRITICALSECTION_SPIN 4000
++typedef struct
++{
++ CRITICAL_SECTION h;
++}
++osip_mutex_t;
++#else
++
++typedef struct
++{
++ HANDLE h;
++}
++osip_mutex_t;
++#endif
++
++typedef struct
++{
++ HANDLE h;
++}
++osip_sem_t;
++#endif
++
++#ifdef __VXWORKS_OS__
++#include <semaphore.h>
++#include <semLib.h>
++typedef struct semaphore osip_mutex_t;
++typedef sem_t osip_sem_t;
++#endif
++
++#ifdef __PSOS__
++#include <Types.h>
++#include <os.h>
++typedef struct
++{
++ UInt32 id;
++}
++osip_mutex_t;
++typedef struct
++{
++ UInt32 id;
++}
++osip_sem_t;
++#endif
++
++
++/* Condition variable abstraction layer definition */
++
++/**
++ * Structure for referencing a condition variable element.
++ * @var osip_cond_t
++ */
++#if defined(HAVE_PTHREAD) || defined(HAVE_PTH_PTHREAD_H) || defined(HAVE_PTHREAD_WIN32)
++typedef struct osip_cond
++{
++ pthread_cond_t cv;
++} osip_cond_t;
++#endif
++
++#if (defined(WIN32) || defined(_WIN32_WCE)) && !defined(HAVE_PTHREAD_WIN32)
++typedef struct osip_cond
++{
++ struct osip_mutex *mut;
++ struct osip_sem *sem;
++} osip_cond_t;
++#endif
++
++#if defined(__PSOS__) || defined(__VXWORKS_OS__)
++typedef struct osip_cond
++{
++ struct osip_sem *sem;
++} osip_cond_t;
++#endif
++
++#endif /* #ifdef OSIP_MT */
++
++#endif /* #ifndef DOXYGEN */
++
++#endif /* #ifndef _INTERNAL_H_ */
+
diff -ruN linphone-base.orig/files/patch-exosip::osip_negotiation.c linphone-base/files/patch-exosip::osip_negotiation.c
--- linphone-base.orig/files/patch-exosip::osip_negotiation.c Thu Jan 1 01:00:00 1970
+++ linphone-base/files/patch-exosip::osip_negotiation.c Fri Nov 24 19:01:06 2006
@@ -0,0 +1,1301 @@
+--- exosip.orig/osip_negotiation.c Thu Jan 1 01:00:00 1970
++++ exosip/osip_negotiation.c Sun Nov 19 14:34:43 2006
+@@ -0,0 +1,1297 @@
++/*
++ The oSIP library implements the Session Initiation Protocol (SIP -rfc3261-)
++ Copyright (C) 2001,2002,2003 Aymeric MOIZARD jack at atosc.org
++
++ 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++*/
++
++
++#include "osip_negotiation.h"
++#include "internal.h"
++
++static int sdp_partial_clone (osip_negotiation_t * config,
++ osip_negotiation_ctx_t * con,
++ sdp_message_t * remote, sdp_message_t ** dest);
++static int sdp_confirm_media (osip_negotiation_t * config,
++ osip_negotiation_ctx_t * context,
++ sdp_message_t * remote, sdp_message_t ** dest);
++static __payload_t *osip_negotiation_find_audio_payload (osip_negotiation_t *
++ cfg, char *payload);
++static __payload_t *osip_negotiation_find_video_payload (osip_negotiation_t *
++ cfg, char *payload);
++static __payload_t *osip_negotiation_find_other_payload (osip_negotiation_t *
++ cfg, char *payload);
++
++
++
++int
++osip_negotiation_ctx_init (osip_negotiation_ctx_t ** con)
++{
++ (*con) =
++ (osip_negotiation_ctx_t *) osip_malloc (sizeof (osip_negotiation_ctx_t));
++ if (*con == NULL)
++ return -1;
++ (*con)->mycontext = NULL; /* fixed Sep 24 2003 */
++ (*con)->remote = NULL;
++ (*con)->local = NULL;
++ return 0;
++}
++
++void
++osip_negotiation_ctx_free (osip_negotiation_ctx_t * con)
++{
++ if (con == NULL)
++ return;
++ sdp_message_free (con->remote);
++ sdp_message_free (con->local);
++ osip_free (con);
++}
++
++/* this method is used by end-user application so any pointer can
++ be associated with this context (usefull to link with your own context */
++int
++osip_negotiation_ctx_set_mycontext (osip_negotiation_ctx_t * con,
++ void *my_instance)
++{
++ if (con == NULL)
++ return -1;
++ con->mycontext = my_instance;
++ return 0;
++}
++
++void *
++osip_negotiation_ctx_get_mycontext (osip_negotiation_ctx_t * con)
++{
++ if (con == NULL)
++ return NULL;
++ return con->mycontext;
++}
++
++sdp_message_t *
++osip_negotiation_ctx_get_local_sdp (osip_negotiation_ctx_t * con)
++{
++ if (con == NULL)
++ return NULL;
++ return con->local;
++}
++
++int
++osip_negotiation_ctx_set_local_sdp (osip_negotiation_ctx_t * con,
++ sdp_message_t * sdp)
++{
++ if (con == NULL)
++ return -1;
++ con->local = sdp;
++ return 0;
++}
++
++sdp_message_t *
++osip_negotiation_ctx_get_remote_sdp (osip_negotiation_ctx_t * con)
++{
++ if (con == NULL)
++ return NULL;
++ return con->remote;
++}
++
++int
++osip_negotiation_ctx_set_remote_sdp (osip_negotiation_ctx_t * con,
++ sdp_message_t * sdp)
++{
++ if (con == NULL)
++ return -1;
++ con->remote = sdp;
++ return 0;
++}
++
++int
++__payload_init (__payload_t ** payload)
++{
++ *payload = (__payload_t *) osip_malloc (sizeof (__payload_t));
++ if (*payload == NULL)
++ return -1;
++ (*payload)->payload = NULL;
++ (*payload)->number_of_port = NULL;
++ (*payload)->proto = NULL;
++ (*payload)->c_nettype = NULL;
++ (*payload)->c_addrtype = NULL;
++ (*payload)->c_addr = NULL;
++ (*payload)->c_addr_multicast_ttl = NULL;
++ (*payload)->c_addr_multicast_int = NULL;
++ (*payload)->a_rtpmap = NULL;
++ return 0;
++}
++
++void
++__payload_free (__payload_t * payload)
++{
++ if (payload == NULL)
++ return;
++ osip_free (payload->payload);
++ osip_free (payload->number_of_port);
++ osip_free (payload->proto);
++ osip_free (payload->c_nettype);
++ osip_free (payload->c_addrtype);
++ osip_free (payload->c_addr);
++ osip_free (payload->c_addr_multicast_ttl);
++ osip_free (payload->c_addr_multicast_int);
++ osip_free (payload->a_rtpmap);
++ osip_free (payload);
++}
++
++int
++osip_negotiation_init (osip_negotiation_t ** config_out)
++{
++ osip_negotiation_t *config;
++
++ config = (osip_negotiation_t *) osip_malloc (sizeof (osip_negotiation_t));
++ if (config == NULL)
++ return -1;
++ config->o_username = NULL;
++ config->o_session_id = NULL;
++ config->o_session_version = NULL;
++ config->o_nettype = NULL;
++ config->o_addrtype = NULL;
++ config->o_addr = NULL;
++
++ config->c_nettype = NULL;
++ config->c_addrtype = NULL;
++ config->c_addr = NULL;
++ config->c_addr_multicast_ttl = NULL;
++ config->c_addr_multicast_int = NULL;
++
++ /* supported codec for the SIP User Agent */
++ config->audio_codec = (osip_list_t *) osip_malloc (sizeof (osip_list_t));
++ osip_list_init (config->audio_codec);
++ config->video_codec = (osip_list_t *) osip_malloc (sizeof (osip_list_t));
++ osip_list_init (config->video_codec);
++ config->other_codec = (osip_list_t *) osip_malloc (sizeof (osip_list_t));
++ osip_list_init (config->other_codec);
++
++ config->fcn_set_info = NULL;
++ config->fcn_set_uri = NULL;
++ config->fcn_set_emails = NULL;
++ config->fcn_set_phones = NULL;
++ config->fcn_set_attributes = NULL;
++ config->fcn_accept_audio_codec = NULL;
++ config->fcn_accept_video_codec = NULL;
++ config->fcn_accept_other_codec = NULL;
++
++ *config_out = config;
++
++ return 0;
++}
++
++void
++osip_negotiation_free (osip_negotiation_t * config)
++{
++ if (config == NULL)
++ return;
++ osip_free (config->o_username);
++ osip_free (config->o_session_id);
++ osip_free (config->o_session_version);
++ osip_free (config->o_nettype);
++ osip_free (config->o_addrtype);
++ osip_free (config->o_addr);
++
++ osip_free (config->c_nettype);
++ osip_free (config->c_addrtype);
++ osip_free (config->c_addr);
++ osip_free (config->c_addr_multicast_ttl);
++ osip_free (config->c_addr_multicast_int);
++
++ osip_list_special_free (config->audio_codec,
++ (void *(*)(void *)) &__payload_free);
++ osip_list_special_free (config->video_codec,
++ (void *(*)(void *)) &__payload_free);
++ osip_list_special_free (config->other_codec,
++ (void *(*)(void *)) &__payload_free);
++
++ /* other are pointer to func, they don't need free() calls */
++
++ /* yes, this is done here... :) */
++ osip_free (config);
++}
++
++int
++osip_negotiation_set_o_username (osip_negotiation_t * config, char *tmp)
++{
++ if (config == NULL)
++ return -1;
++ config->o_username = tmp;
++ return 0;
++}
++
++int
++osip_negotiation_set_o_session_id (osip_negotiation_t * config, char *tmp)
++{
++ if (config == NULL)
++ return -1;
++ config->o_session_id = tmp;
++ return 0;
++}
++
++int
++osip_negotiation_set_o_session_version (osip_negotiation_t * config, char *tmp)
++{
++ if (config == NULL)
++ return -1;
++ config->o_session_version = tmp;
++ return 0;
++}
++
++int
++osip_negotiation_set_o_nettype (osip_negotiation_t * config, char *tmp)
++{
++ if (config == NULL)
++ return -1;
++ config->o_nettype = tmp;
++ return 0;
++}
++
++int
++osip_negotiation_set_o_addrtype (osip_negotiation_t * config, char *tmp)
++{
++ if (config == NULL)
++ return -1;
++ config->o_addrtype = tmp;
++ return 0;
++}
++
++int
++osip_negotiation_set_o_addr (osip_negotiation_t * config, char *tmp)
++{
++ if (config == NULL)
++ return -1;
++ config->o_addr = tmp;
++ return 0;
++}
++
++int
++osip_negotiation_set_c_nettype (osip_negotiation_t * config, char *tmp)
++{
++ if (config == NULL)
++ return -1;
++ config->c_nettype = tmp;
++ return 0;
++}
++
++int
++osip_negotiation_set_c_addrtype (osip_negotiation_t * config, char *tmp)
++{
++ if (config == NULL)
++ return -1;
++ config->c_addrtype = tmp;
++ return 0;
++}
++
++int
++osip_negotiation_set_c_addr (osip_negotiation_t * config, char *tmp)
++{
++ if (config == NULL)
++ return -1;
++ config->c_addr = tmp;
++ return 0;
++}
++
++int
++osip_negotiation_set_c_addr_multicast_ttl (osip_negotiation_t * config, char *tmp)
++{
++ if (config == NULL)
++ return -1;
++ config->c_addr_multicast_ttl = tmp;
++ return 0;
++}
++
++int
++osip_negotiation_set_c_addr_multicast_int (osip_negotiation_t * config, char *tmp)
++{
++ if (config == NULL)
++ return -1;
++ config->c_addr_multicast_int = tmp;
++ return 0;
++}
++
++int
++osip_negotiation_add_support_for_audio_codec (osip_negotiation_t * config,
++ char *payload,
++ char *number_of_port,
++ char *proto, char *c_nettype,
++ char *c_addrtype, char *c_addr,
++ char *c_addr_multicast_ttl,
++ char *c_addr_multicast_int,
++ char *a_rtpmap)
++{
++ int i;
++ __payload_t *my_payload;
++
++ i = __payload_init (&my_payload);
++ if (i != 0)
++ return -1;
++ my_payload->payload = payload;
++ my_payload->number_of_port = number_of_port;
++ my_payload->proto = proto;
++ my_payload->c_nettype = c_nettype;
++ my_payload->c_addrtype = c_addrtype;
++ my_payload->c_addr = c_addr;
++ my_payload->c_addr_multicast_ttl = c_addr_multicast_ttl;
++ my_payload->c_addr_multicast_int = c_addr_multicast_int;
++ my_payload->a_rtpmap = a_rtpmap;
++ osip_list_add (config->audio_codec, my_payload, -1);
++ return 0;
++}
++
++int
++osip_negotiation_add_support_for_video_codec (osip_negotiation_t * config,
++ char *payload,
++ char *number_of_port,
++ char *proto, char *c_nettype,
++ char *c_addrtype, char *c_addr,
++ char *c_addr_multicast_ttl,
++ char *c_addr_multicast_int,
++ char *a_rtpmap)
++{
++ int i;
++ __payload_t *my_payload;
++
++ i = __payload_init (&my_payload);
++ if (i != 0)
++ return -1;
++ my_payload->payload = payload;
++ my_payload->number_of_port = number_of_port;
++ my_payload->proto = proto;
++ my_payload->c_nettype = c_nettype;
++ my_payload->c_addrtype = c_addrtype;
++ my_payload->c_addr = c_addr;
++ my_payload->c_addr_multicast_ttl = c_addr_multicast_ttl;
++ my_payload->c_addr_multicast_int = c_addr_multicast_int;
++ my_payload->a_rtpmap = a_rtpmap;
++ osip_list_add (config->video_codec, my_payload, -1);
++ return 0;
++}
++
++int
++osip_negotiation_add_support_for_other_codec (osip_negotiation_t * config,
++ char *payload,
++ char *number_of_port,
++ char *proto, char *c_nettype,
++ char *c_addrtype, char *c_addr,
++ char *c_addr_multicast_ttl,
++ char *c_addr_multicast_int,
++ char *a_rtpmap)
++{
++ int i;
++ __payload_t *my_payload;
++
++ i = __payload_init (&my_payload);
++ if (i != 0)
++ return -1;
++ my_payload->payload = payload;
++ my_payload->number_of_port = number_of_port;
++ my_payload->proto = proto;
++ my_payload->c_nettype = c_nettype;
++ my_payload->c_addrtype = c_addrtype;
++ my_payload->c_addr = c_addr;
++ my_payload->c_addr_multicast_ttl = c_addr_multicast_ttl;
++ my_payload->c_addr_multicast_int = c_addr_multicast_int;
++ my_payload->a_rtpmap = a_rtpmap;
++ osip_list_add (config->other_codec, my_payload, -1);
++ return 0;
++}
++
++int
++osip_negotiation_remove_audio_payloads (osip_negotiation_t * config)
++{
++ osip_list_special_free (config->audio_codec,
++ (void *(*)(void *)) &__payload_free);
++ config->audio_codec = (osip_list_t *) osip_malloc (sizeof (osip_list_t));
++ osip_list_init (config->audio_codec);
++ return 0;
++}
++
++int
++osip_negotiation_remove_video_payloads (osip_negotiation_t * config)
++{
++ osip_list_special_free (config->video_codec,
++ (void *(*)(void *)) &__payload_free);
++ config->video_codec = (osip_list_t *) osip_malloc (sizeof (osip_list_t));
++ osip_list_init (config->video_codec);
++ return 0;
++}
++
++int
++osip_negotiation_remove_other_payloads (osip_negotiation_t * config)
++{
++ osip_list_special_free (config->other_codec,
++ (void *(*)(void *)) &__payload_free);
++ config->other_codec = (osip_list_t *) osip_malloc (sizeof (osip_list_t));
++ osip_list_init (config->other_codec);
++ return 0;
++}
++
++static __payload_t *
++osip_negotiation_find_audio_payload (osip_negotiation_t * config, char *payload)
++{
++ __payload_t *my;
++ size_t length = strlen (payload);
++ int pos = 0;
++
++ if (payload == NULL)
++ return NULL;
++ while (!osip_list_eol (config->audio_codec, pos))
++ {
++ my = (__payload_t *) osip_list_get (config->audio_codec, pos);
++ if (strlen (my->payload) == length)
++ if (0 == strncmp (my->payload, payload, length))
++ return my;
++ pos++;
++ }
++ return NULL;
++}
++
++static __payload_t *
++osip_negotiation_find_video_payload (osip_negotiation_t * config, char *payload)
++{
++ __payload_t *my;
++ size_t length = strlen (payload);
++ int pos = 0;
++
++ if (payload == NULL)
++ return NULL;
++ while (!osip_list_eol (config->video_codec, pos))
++ {
++ my = (__payload_t *) osip_list_get (config->video_codec, pos);
++ if (strlen (my->payload) == length)
++ if (0 == strncmp (my->payload, payload, length))
++ return my;
++ pos++;
++ }
++ return NULL;
++}
++
++static __payload_t *
++osip_negotiation_find_other_payload (osip_negotiation_t * config, char *payload)
++{
++ __payload_t *my;
++ size_t length = strlen (payload);
++ int pos = 0;
++
++ if (payload == NULL)
++ return NULL;
++ while (!osip_list_eol (config->other_codec, pos))
++ {
++ my = (__payload_t *) osip_list_get (config->other_codec, pos);
++ if (strlen (my->payload) == length)
++ if (0 == strncmp (my->payload, payload, length))
++ return my;
++ pos++;
++ }
++ return NULL;
++}
++
++int
++osip_negotiation_set_fcn_set_info (osip_negotiation_t * config,
++ int (*fcn) (osip_negotiation_ctx_t *,
++ sdp_message_t *))
++{
++ if (config == NULL)
++ return -1;
++ config->fcn_set_info = (int (*)(void *, sdp_message_t *)) fcn;
++ return 0;
++}
++
++int
++osip_negotiation_set_fcn_set_uri (osip_negotiation_t * config,
++ int (*fcn) (osip_negotiation_ctx_t *,
++ sdp_message_t *))
++{
++ if (config == NULL)
++ return -1;
++ config->fcn_set_uri = (int (*)(void *, sdp_message_t *)) fcn;
++ return 0;
++}
++
++int
++osip_negotiation_set_fcn_set_emails (osip_negotiation_t * config,
++ int (*fcn) (osip_negotiation_ctx_t *,
++ sdp_message_t *))
++{
++ if (config == NULL)
++ return -1;
++ config->fcn_set_emails = (int (*)(void *, sdp_message_t *)) fcn;
++ return 0;
++}
++
++int
++osip_negotiation_set_fcn_set_phones (osip_negotiation_t * config,
++ int (*fcn) (osip_negotiation_ctx_t *,
++ sdp_message_t *))
++{
++ if (config == NULL)
++ return -1;
++ config->fcn_set_phones = (int (*)(void *, sdp_message_t *)) fcn;
++ return 0;
++}
++
++int
++osip_negotiation_set_fcn_set_attributes (osip_negotiation_t * config,
++ int (*fcn) (osip_negotiation_ctx_t *,
++ sdp_message_t *, int))
++{
++ if (config == NULL)
++ return -1;
++ config->fcn_set_attributes = (int (*)(void *, sdp_message_t *, int)) fcn;
++ return 0;
++}
++
++int
++osip_negotiation_set_fcn_accept_audio_codec (osip_negotiation_t * config,
++ int (*fcn)
++ (osip_negotiation_ctx_t *,
++ char *, char *, int, char *))
++{
++ if (config == NULL)
++ return -1;
++ config->fcn_accept_audio_codec = (int (*)(void *, char *,
++ char *, int, char *)) fcn;
++ return 0;
++}
++
++int
++osip_negotiation_set_fcn_accept_video_codec (osip_negotiation_t * config,
++ int (*fcn)
++ (osip_negotiation_ctx_t *,
++ char *, char *, int, char *))
++{
++ if (config == NULL)
++ return -1;
++ config->fcn_accept_video_codec = (int (*)(void *, char *,
++ char *, int, char *)) fcn;
++ return 0;
++}
++
++int
++osip_negotiation_set_fcn_accept_other_codec (osip_negotiation_t * config,
++ int (*fcn)
++ (osip_negotiation_ctx_t *,
++ char *, char *, char *, char *))
++{
++ if (config == NULL)
++ return -1;
++ config->fcn_accept_other_codec = (int (*)(void *, char *,
++ char *, char *, char *)) fcn;
++ return 0;
++}
++
++int
++osip_negotiation_set_fcn_get_audio_port (osip_negotiation_t * config,
++ char *(*fcn) (osip_negotiation_ctx_t
++ *, int))
++{
++ if (config == NULL)
++ return -1;
++ config->fcn_get_audio_port = (char *(*)(void *, int)) fcn;
++ return 0;
++}
++
++int
++osip_negotiation_set_fcn_get_video_port (osip_negotiation_t * config,
++ char *(*fcn) (osip_negotiation_ctx_t
++ *, int))
++{
++ if (config == NULL)
++ return -1;
++ config->fcn_get_video_port = (char *(*)(void *, int)) fcn;
++ return 0;
++}
++
++int
++osip_negotiation_set_fcn_get_other_port (osip_negotiation_t * config,
++ char *(*fcn) (osip_negotiation_ctx_t
++ *, int))
++{
++ if (config == NULL)
++ return -1;
++ config->fcn_get_other_port = (char *(*)(void *, int)) fcn;
++ return 0;
++}
++
++static int
++sdp_partial_clone (osip_negotiation_t * config,
++ osip_negotiation_ctx_t * con, sdp_message_t * remote,
++ sdp_message_t ** dest)
++{
++ int i;
++
++ sdp_message_v_version_set (*dest, osip_strdup ("0"));
++
++ /* those fields MUST be set */
++ sdp_message_o_origin_set (*dest,
++ osip_strdup (config->o_username),
++ osip_strdup (config->o_session_id),
++ osip_strdup (config->o_session_version),
++ osip_strdup (config->o_nettype),
++ osip_strdup (config->o_addrtype),
++ osip_strdup (config->o_addr));
++ sdp_message_s_name_set (*dest, osip_strdup (remote->s_name));
++ if (config->fcn_set_info != NULL)
++ config->fcn_set_info (con, *dest);
++ if (config->fcn_set_uri != NULL)
++ config->fcn_set_uri (con, *dest);
++ if (config->fcn_set_emails != NULL)
++ config->fcn_set_emails (con, *dest);
++ if (config->fcn_set_phones != NULL)
++ config->fcn_set_phones (con, *dest);
++ if (config->c_nettype != NULL)
++ sdp_message_c_connection_add (*dest, -1,
++ osip_strdup (config->c_nettype),
++ osip_strdup (config->c_addrtype),
++ osip_strdup (config->c_addr),
++ osip_strdup (config->c_addr_multicast_ttl),
++ osip_strdup (config->c_addr_multicast_int));
++
++ { /* offer-answer draft says we must copy the "t=" line */
++ char *tmp = sdp_message_t_start_time_get (remote, 0);
++ char *tmp2 = sdp_message_t_stop_time_get (remote, 0);
++
++ if (tmp == NULL || tmp2 == NULL)
++ return -1; /* no t line?? */
++ i =
++ sdp_message_t_time_descr_add (*dest, osip_strdup (tmp), osip_strdup (tmp2));
++ if (i != 0)
++ return -1;
++ }
++ if (config->fcn_set_attributes != NULL)
++ config->fcn_set_attributes (con, *dest, -1);
++ return 0;
++}
++
++static int
++sdp_confirm_media (osip_negotiation_t * config,
++ osip_negotiation_ctx_t * context, sdp_message_t * remote,
++ sdp_message_t ** dest)
++{
++ char *payload;
++ char *tmp, *tmp2, *tmp3, *tmp4;
++ int ret;
++ int i;
++ int k;
++ int audio_qty = 0; /* accepted audio line: do not accept more than one */
++ int video_qty = 0;
++
++ i = 0;
++ while (!sdp_message_endof_media (remote, i))
++ {
++ tmp = sdp_message_m_media_get (remote, i);
++ tmp2 = sdp_message_m_port_get (remote, i);
++ tmp3 = sdp_message_m_number_of_port_get (remote, i);
++ tmp4 = sdp_message_m_proto_get (remote, i);
++
++ if (tmp == NULL)
++ return -1;
++ sdp_message_m_media_add (*dest, osip_strdup (tmp), osip_strdup ("0"),
++ NULL, osip_strdup (tmp4));
++ k = 0;
++ if (0 == strncmp (tmp, "audio", 5))
++ {
++ do
++ {
++ payload = sdp_message_m_payload_get (remote, i, k);
++ if (payload != NULL)
++ {
++ __payload_t *my_payload =
++ osip_negotiation_find_audio_payload (config, payload);
++
++ if (my_payload != NULL) /* payload is supported */
++ {
++ ret = -1; /* somtimes, codec can be refused even if supported */
++ if (config->fcn_accept_audio_codec != NULL)
++ ret = config->fcn_accept_audio_codec (context, tmp2,
++ tmp3, audio_qty,
++ payload);
++ if (0 == ret)
++ {
++ sdp_message_m_payload_add (*dest, i,
++ osip_strdup (payload));
++ if (my_payload->a_rtpmap != NULL)
++ sdp_message_a_attribute_add (*dest, i,
++ osip_strdup
++ ("rtpmap"),
++ osip_strdup
++ (my_payload->a_rtpmap));
++ if (my_payload->c_nettype != NULL)
++ {
++ sdp_media_t *med =
++ osip_list_get ((*dest)->m_medias, i);
++
++ if (osip_list_eol (med->c_connections, 0))
++ sdp_message_c_connection_add (*dest, i,
++ osip_strdup
++ (my_payload->
++ c_nettype),
++ osip_strdup
++ (my_payload->
++ c_addrtype),
++ osip_strdup
++ (my_payload->
++ c_addr),
++ osip_strdup
++ (my_payload->
++ c_addr_multicast_ttl),
++ osip_strdup
++ (my_payload->
++ c_addr_multicast_int));
++ }
++ }
++ }
++ }
++ k++;
++ }
++ while (payload != NULL);
++ if (NULL != sdp_message_m_payload_get (*dest, i, 0))
++ audio_qty = 1;
++ } else if (0 == strncmp (tmp, "video", 5))
++ {
++ do
++ {
++ payload = sdp_message_m_payload_get (remote, i, k);
++ if (payload != NULL)
++ {
++ __payload_t *my_payload =
++ osip_negotiation_find_video_payload (config, payload);
++
++ if (my_payload != NULL) /* payload is supported */
++ {
++ ret = -1;
++ if (config->fcn_accept_video_codec != NULL)
++ ret =
++ config->fcn_accept_video_codec (context, tmp2, tmp3,
++ video_qty, payload);
++ if (0 == ret)
++ {
++ sdp_message_m_payload_add (*dest, i,
++ osip_strdup (payload));
++ /* TODO set the attribute list (rtpmap..) */
++ if (my_payload->a_rtpmap != NULL)
++ sdp_message_a_attribute_add (*dest, i,
++ osip_strdup
++ ("rtpmap"),
++ osip_strdup
++ (my_payload->a_rtpmap));
++ if (my_payload->c_nettype != NULL)
++ {
++ sdp_media_t *med =
++ osip_list_get ((*dest)->m_medias, i);
++
++ if (osip_list_eol (med->c_connections, 0))
++ sdp_message_c_connection_add (*dest, i,
++ osip_strdup
++ (my_payload->
++ c_nettype),
++ osip_strdup
++ (my_payload->
++ c_addrtype),
++ osip_strdup
++ (my_payload->
++ c_addr),
++ osip_strdup
++ (my_payload->
++ c_addr_multicast_ttl),
++ osip_strdup
++ (my_payload->
++ c_addr_multicast_int));
++ }
++ }
++ }
++ }
++ k++;
++ }
++ while (payload != NULL);
++ if (NULL != sdp_message_m_payload_get (*dest, i, 0))
++ video_qty = 1;
++ } else
++ {
++ do
++ {
++ payload = sdp_message_m_payload_get (remote, i, k);
++ if (payload != NULL)
++ {
++ __payload_t *my_payload =
++ osip_negotiation_find_other_payload (config, payload);
++
++ if (my_payload != NULL) /* payload is supported */
++ {
++ ret = -1;
++ if (config->fcn_accept_other_codec != NULL)
++ ret =
++ config->fcn_accept_other_codec (context, tmp, tmp2,
++ tmp3, payload);
++ if (0 == ret)
++ {
++ sdp_message_m_payload_add (*dest, i,
++ osip_strdup (payload));
++ /* rtpmap has no meaning here! */
++ if (my_payload->c_nettype != NULL)
++ {
++ sdp_media_t *med =
++ osip_list_get ((*dest)->m_medias, i);
++
++ if (osip_list_eol (med->c_connections, 0))
++ sdp_message_c_connection_add (*dest, i,
++ osip_strdup
++ (my_payload->
++ c_nettype),
++ osip_strdup
++ (my_payload->
++ c_addrtype),
++ osip_strdup
++ (my_payload->
++ c_addr),
++ osip_strdup
++ (my_payload->
++ c_addr_multicast_ttl),
++ osip_strdup
++ (my_payload->
++ c_addr_multicast_int));
++ }
++ }
++ }
++ }
++ k++;
++ }
++ while (payload != NULL);
++ }
++ i++;
++ }
++ return 0;
++}
++
++int
++osip_negotiation_ctx_execute_negotiation (osip_negotiation_t * config,
++ osip_negotiation_ctx_t * context)
++{
++ int m_lines_that_match = 0;
++ sdp_message_t *remote;
++ sdp_message_t *local;
++ int i;
++
++ if (context == NULL)
++ return -1;
++ remote = context->remote;
++ if (remote == NULL)
++ return -1;
++
++ i = sdp_message_init (&local);
++ if (i != 0)
++ return -1;
++
++ if (0 != strncmp (remote->v_version, "0", 1))
++ {
++ sdp_message_free (local);
++ /* sdp_context->fcn_wrong_version(context); */
++ return 406; /* Not Acceptable */
++ }
++
++ i = sdp_partial_clone (config, context, remote, &local);
++ if (i != 0)
++ {
++ sdp_message_free (local);
++ return -1;
++ }
++ i = sdp_confirm_media (config, context, remote, &local);
++ if (i != 0)
++ {
++ sdp_message_free (local);
++ return i;
++ }
++
++ i = 0;
++ while (!sdp_message_endof_media (local, i))
++ {
++ /* this is to refuse each line with no codec that matches! */
++ if (NULL == sdp_message_m_payload_get (local, i, 0))
++ {
++ sdp_media_t *med = osip_list_get ((local)->m_medias, i);
++ char *str = sdp_message_m_payload_get (remote, i, 0);
++
++ sdp_message_m_payload_add (local, i, osip_strdup (str));
++ osip_free (med->m_port);
++ med->m_port = osip_strdup ("0"); /* refuse this line */
++ } else
++ { /* number of "m" lines that match */
++ sdp_media_t *med = osip_list_get (local->m_medias, i);
++
++ m_lines_that_match++;
++ osip_free (med->m_port);
++ /* AMD: use the correct fcn_get_xxx_port method: */
++ if (0 == strcmp (med->m_media, "audio"))
++ {
++ if (config->fcn_get_audio_port != NULL)
++ med->m_port = config->fcn_get_audio_port (context, i);
++ else
++ med->m_port = osip_strdup ("0"); /* should never happen */
++ } else if (0 == strcmp (med->m_media, "video"))
++ {
++ if (config->fcn_get_video_port != NULL)
++ med->m_port = config->fcn_get_video_port (context, i);
++ else
++ med->m_port = osip_strdup ("0"); /* should never happen */
++ } else
++ {
++ if (config->fcn_get_other_port != NULL)
++ med->m_port = config->fcn_get_other_port (context, i);
++ else
++ med->m_port = osip_strdup ("0"); /* should never happen */
++ }
++ }
++ i++;
++ }
++ if (m_lines_that_match > 0)
++ {
++ context->local = local;
++ return 200;
++ } else
++ {
++ sdp_message_free (local);
++ return 415;
++ }
++
++}
++
++int
++osip_negotiation_sdp_build_offer (osip_negotiation_t * config,
++ osip_negotiation_ctx_t * con,
++ sdp_message_t ** sdp, char *audio_port,
++ char *video_port)
++{
++ int i;
++ int media_line = 0;
++
++ i = sdp_message_init (sdp);
++ if (i != 0)
++ return -1;
++
++ sdp_message_v_version_set (*sdp, osip_strdup ("0"));
++
++ /* those fields MUST be set */
++ sdp_message_o_origin_set (*sdp,
++ osip_strdup (config->o_username),
++ osip_strdup (config->o_session_id),
++ osip_strdup (config->o_session_version),
++ osip_strdup (config->o_nettype),
++ osip_strdup (config->o_addrtype),
++ osip_strdup (config->o_addr));
++ sdp_message_s_name_set (*sdp, osip_strdup ("A call"));
++ if (config->fcn_set_info != NULL)
++ config->fcn_set_info (con, *sdp);
++ if (config->fcn_set_uri != NULL)
++ config->fcn_set_uri (con, *sdp);
++ if (config->fcn_set_emails != NULL)
++ config->fcn_set_emails (con, *sdp);
++ if (config->fcn_set_phones != NULL)
++ config->fcn_set_phones (con, *sdp);
++ if (config->c_nettype != NULL)
++ sdp_message_c_connection_add (*sdp, -1,
++ osip_strdup (config->c_nettype),
++ osip_strdup (config->c_addrtype),
++ osip_strdup (config->c_addr),
++ osip_strdup (config->c_addr_multicast_ttl),
++ osip_strdup (config->c_addr_multicast_int));
++
++ i = sdp_message_t_time_descr_add (*sdp, osip_strdup ("0"), osip_strdup ("0"));
++ if (i != 0)
++ return -1;
++
++ if (config->fcn_set_attributes != NULL)
++ config->fcn_set_attributes (con, *sdp, -1);
++
++
++ /* add all audio codec */
++ if (!osip_list_eol (config->audio_codec, 0))
++ {
++ int pos = 0;
++ __payload_t *my = (__payload_t *) osip_list_get (config->audio_codec, pos);
++
++ /* all media MUST have the same PROTO, PORT. */
++ sdp_message_m_media_add (*sdp, osip_strdup ("audio"),
++ osip_strdup (audio_port),
++ osip_strdup (my->number_of_port),
++ osip_strdup (my->proto));
++
++ while (!osip_list_eol (config->audio_codec, pos))
++ {
++ my = (__payload_t *) osip_list_get (config->audio_codec, pos);
++ sdp_message_m_payload_add (*sdp, media_line, osip_strdup (my->payload));
++ if (my->a_rtpmap != NULL)
++ sdp_message_a_attribute_add (*sdp, media_line,
++ osip_strdup ("rtpmap"),
++ osip_strdup (my->a_rtpmap));
++ pos++;
++ }
++ media_line++;
++ }
++
++ /* add all video codec */
++ if (!osip_list_eol (config->video_codec, 0))
++ {
++ int pos = 0;
++ __payload_t *my = (__payload_t *) osip_list_get (config->video_codec, pos);
++
++ /* all media MUST have the same PROTO, PORT. */
++ sdp_message_m_media_add (*sdp, osip_strdup ("video"),
++ osip_strdup (video_port),
++ osip_strdup (my->number_of_port),
++ osip_strdup (my->proto));
++
++ while (!osip_list_eol (config->video_codec, pos))
++ {
++ my = (__payload_t *) osip_list_get (config->video_codec, pos);
++ sdp_message_m_payload_add (*sdp, media_line, osip_strdup (my->payload));
++ if (my->a_rtpmap != NULL)
++ sdp_message_a_attribute_add (*sdp, media_line,
++ osip_strdup ("rtpmap"),
++ osip_strdup (my->a_rtpmap));
++ pos++;
++ }
++ media_line++;
++ }
++ return 0;
++}
++
++/* build the SDP packet with only one audio codec and one video codec.
++ * - Usefull if you don't want to restrict proposal to one codec only -
++ * - Limitation, only one codec will be proposed
++ */
++int
++__osip_negotiation_sdp_build_offer (osip_negotiation_t * config,
++ osip_negotiation_ctx_t * con,
++ sdp_message_t ** sdp, char *audio_port,
++ char *video_port, char *audio_codec,
++ char *video_codec)
++{
++ int i;
++ int media_line = 0;
++
++ i = sdp_message_init (sdp);
++ if (i != 0)
++ return -1;
++
++ sdp_message_v_version_set (*sdp, osip_strdup ("0"));
++
++ /* those fields MUST be set */
++ sdp_message_o_origin_set (*sdp,
++ osip_strdup (config->o_username),
++ osip_strdup (config->o_session_id),
++ osip_strdup (config->o_session_version),
++ osip_strdup (config->o_nettype),
++ osip_strdup (config->o_addrtype),
++ osip_strdup (config->o_addr));
++ sdp_message_s_name_set (*sdp, osip_strdup ("A call"));
++ if (config->fcn_set_info != NULL)
++ config->fcn_set_info (con, *sdp);
++ if (config->fcn_set_uri != NULL)
++ config->fcn_set_uri (con, *sdp);
++ if (config->fcn_set_emails != NULL)
++ config->fcn_set_emails (con, *sdp);
++ if (config->fcn_set_phones != NULL)
++ config->fcn_set_phones (con, *sdp);
++ if (config->c_nettype != NULL)
++ sdp_message_c_connection_add (*sdp, -1,
++ osip_strdup (config->c_nettype),
++ osip_strdup (config->c_addrtype),
++ osip_strdup (config->c_addr),
++ osip_strdup (config->c_addr_multicast_ttl),
++ osip_strdup (config->c_addr_multicast_int));
++
++ { /* offer-answer draft says we must copy the "t=" line */
++ time_t now = time (NULL);
++ char *tmp = osip_malloc (15);
++ char *tmp2 = osip_malloc (15);
++
++ sprintf (tmp, "%li", now);
++ sprintf (tmp2, "%li", now + 3600);
++
++ i = sdp_message_t_time_descr_add (*sdp, tmp, tmp2);
++ if (i != 0)
++ return -1;
++ }
++ if (config->fcn_set_attributes != NULL)
++ config->fcn_set_attributes (con, *sdp, -1);
++
++
++ /* add all audio codec */
++ if (audio_codec != NULL)
++ {
++ if (!osip_list_eol (config->audio_codec, 0))
++ {
++ int pos = 0;
++ __payload_t *my =
++ (__payload_t *) osip_list_get (config->audio_codec, pos);
++
++ while (!osip_list_eol (config->audio_codec, pos))
++ {
++ my = (__payload_t *) osip_list_get (config->audio_codec, pos);
++ if (0 == strcmp (audio_codec, my->payload))
++ {
++ /* all media MUST have the same PROTO, PORT. */
++ sdp_message_m_media_add (*sdp, osip_strdup ("audio"),
++ osip_strdup (audio_port),
++ osip_strdup (my->number_of_port),
++ osip_strdup (my->proto));
++ sdp_message_m_payload_add (*sdp, media_line,
++ osip_strdup (my->payload));
++ if (my->a_rtpmap != NULL)
++ sdp_message_a_attribute_add (*sdp, media_line,
++ osip_strdup ("rtpmap"),
++ osip_strdup (my->a_rtpmap));
++ media_line++;
++ break;
++ }
++ pos++;
++ }
++ }
++ }
++
++ /* add all video codec */
++ if (video_codec != NULL)
++ {
++ if (!osip_list_eol (config->video_codec, 0))
++ {
++ int pos = 0;
++ __payload_t *my =
++ (__payload_t *) osip_list_get (config->video_codec, pos);
++
++ while (!osip_list_eol (config->video_codec, pos))
++ {
++ my = (__payload_t *) osip_list_get (config->video_codec, pos);
++ if (0 == strcmp (video_codec, my->payload))
++ {
++ /* all media MUST have the same PROTO, PORT. */
++ sdp_message_m_media_add (*sdp, osip_strdup ("video"),
++ osip_strdup (video_port),
++ osip_strdup (my->number_of_port),
++ osip_strdup (my->proto));
++ sdp_message_m_payload_add (*sdp, media_line,
++ osip_strdup (my->payload));
++ if (my->a_rtpmap != NULL)
++ sdp_message_a_attribute_add (*sdp, media_line,
++ osip_strdup ("rtpmap"),
++ osip_strdup (my->a_rtpmap));
++ media_line++;
++ break;
++ }
++ pos++;
++ }
++ }
++ }
++ return 0;
++}
++
++
++int
++osip_negotiation_sdp_message_put_on_hold (sdp_message_t * sdp)
++{
++ int pos;
++ int pos_media = -1;
++ char *rcvsnd;
++ int recv_send = -1;
++
++ pos = 0;
++ rcvsnd = sdp_message_a_att_field_get (sdp, pos_media, pos);
++ while (rcvsnd != NULL)
++ {
++ if (rcvsnd != NULL && 0 == strcmp (rcvsnd, "sendonly"))
++ {
++ recv_send = 0;
++ } else if (rcvsnd != NULL && (0 == strcmp (rcvsnd, "recvonly")
++ || 0 == strcmp (rcvsnd, "sendrecv")))
++ {
++ recv_send = 0;
++ sprintf (rcvsnd, "sendonly");
++ }
++ pos++;
++ rcvsnd = sdp_message_a_att_field_get (sdp, pos_media, pos);
++ }
++
++ pos_media = 0;
++ while (!sdp_message_endof_media (sdp, pos_media))
++ {
++ pos = 0;
++ rcvsnd = sdp_message_a_att_field_get (sdp, pos_media, pos);
++ while (rcvsnd != NULL)
++ {
++ if (rcvsnd != NULL && 0 == strcmp (rcvsnd, "sendonly"))
++ {
++ recv_send = 0;
++ } else if (rcvsnd != NULL && (0 == strcmp (rcvsnd, "recvonly")
++ || 0 == strcmp (rcvsnd, "sendrecv")))
++ {
++ recv_send = 0;
++ sprintf (rcvsnd, "sendonly");
++ }
++ pos++;
++ rcvsnd = sdp_message_a_att_field_get (sdp, pos_media, pos);
++ }
++ pos_media++;
++ }
++
++ if (recv_send == -1)
++ {
++ /* we need to add a global attribute with a field set to "sendonly" */
++ sdp_message_a_attribute_add (sdp, -1, osip_strdup ("sendonly"), NULL);
++ }
++
++ return 0;
++}
++
++int
++osip_negotiation_sdp_message_put_off_hold (sdp_message_t * sdp)
++{
++ int pos;
++ int pos_media = -1;
++ char *rcvsnd;
++
++ pos = 0;
++ rcvsnd = sdp_message_a_att_field_get (sdp, pos_media, pos);
++ while (rcvsnd != NULL)
++ {
++ if (rcvsnd != NULL && (0 == strcmp (rcvsnd, "sendonly")
++ || 0 == strcmp (rcvsnd, "recvonly")))
++ {
++ sprintf (rcvsnd, "sendrecv");
++ }
++ pos++;
++ rcvsnd = sdp_message_a_att_field_get (sdp, pos_media, pos);
++ }
++
++ pos_media = 0;
++ while (!sdp_message_endof_media (sdp, pos_media))
++ {
++ pos = 0;
++ rcvsnd = sdp_message_a_att_field_get (sdp, pos_media, pos);
++ while (rcvsnd != NULL)
++ {
++ if (rcvsnd != NULL && (0 == strcmp (rcvsnd, "sendonly")
++ || 0 == strcmp (rcvsnd, "recvonly")))
++ {
++ sprintf (rcvsnd, "sendrecv");
++ }
++ pos++;
++ rcvsnd = sdp_message_a_att_field_get (sdp, pos_media, pos);
++ }
++ pos_media++;
++ }
++
++ return 0;
++}
+
diff -ruN linphone-base.orig/files/patch-exosip::osip_negotiation.h linphone-base/files/patch-exosip::osip_negotiation.h
--- linphone-base.orig/files/patch-exosip::osip_negotiation.h Thu Jan 1 01:00:00 1970
+++ linphone-base/files/patch-exosip::osip_negotiation.h Fri Nov 24 19:01:20 2006
@@ -0,0 +1,498 @@
+--- exosip.orig/osip_negotiation.h Thu Jan 1 01:00:00 1970
++++ exosip/osip_negotiation.h Sun Nov 19 14:24:10 2006
+@@ -0,0 +1,495 @@
++/*
++ The oSIP library implements the Session Initiation Protocol (SIP -rfc3261-)
++ Copyright (C) 2001,2002,2003,2004 Aymeric MOIZARD jack at atosc.org
++
++ 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++*/
++
++
++#ifndef _SDP_NEGOC_H_
++#define _SDP_NEGOC_H_
++
++#include <osipparser2/sdp_message.h>
++
++
++/**
++ * @internal
++ * @file osip_negotiation.h
++ * @brief oSIP and SDP offer/answer model Routines
++ *
++ */
++
++/**
++ * @internal
++ * @defgroup oSIP_OAM oSIP and SDP offer/answer model Handling
++ * @{
++ */
++
++#ifdef __cplusplus
++extern "C"
++{
++#endif
++
++/**
++ * Structure for applying the SDP offer/answer negotiation.
++ * The goal is simply to give:
++ * 1. A configuration (osip_negotiation_t)
++ * 2. A remote SDP packet (generally from the INVITE)
++ * The result is the creation of a local answer to
++ * the remote SDP packet.
++ * @var osip_negotiation_ctx_t
++ */
++ typedef struct osip_negotiation_ctx osip_negotiation_ctx_t;
++
++/**
++ * Structure for applying the SDP offer/answer negotiation.
++ * @struct osip_negotiation_ctx
++ */
++ struct osip_negotiation_ctx
++ {
++ void *mycontext; /**< User Defined Pointer */
++ sdp_message_t *remote; /**< Remote SDP offer */
++ sdp_message_t *local; /**< generated SDP answer */
++ };
++
++/**
++ * Allocate a negotiation context.
++ * @param ctx The element to work on.
++ */
++ int osip_negotiation_ctx_init (osip_negotiation_ctx_t ** ctx);
++/**
++ * Free a negotiation context.
++ * @param ctx The element to work on.
++ */
++ void osip_negotiation_ctx_free (osip_negotiation_ctx_t * ctx);
++
++/**
++ * Set the context associated to this negotiation.
++ * @param ctx The element to work on.
++ * @param value A pointer to your personal context.
++ */
++ int osip_negotiation_ctx_set_mycontext (osip_negotiation_ctx_t * ctx,
++ void *value);
++/**
++ * Get the context associated to this negotiation.
++ * @param ctx The element to work on.
++ */
++ void *osip_negotiation_ctx_get_mycontext (osip_negotiation_ctx_t * ctx);
++
++/**
++ * Set the local SDP packet associated to this negotiation.
++ * NOTE: This is done by the 'negotiator'. (You only need to give
++ * the remote SDP packet)
++ * @param ctx The element to work on.
++ * @param sdp The local SDP packet.
++ */
++ int osip_negotiation_ctx_set_local_sdp (osip_negotiation_ctx_t * ctx,
++ sdp_message_t * sdp);
++/**
++ * Get the local SDP packet associated to this negotiation.
++ * @param ctx The element to work on.
++ */
++ sdp_message_t *osip_negotiation_ctx_get_local_sdp (osip_negotiation_ctx_t * ctx);
++/**
++ * Set the remote SDP packet associated to this negotiation.
++ * @param ctx The element to work on.
++ * @param sdp The remote SDP packet.
++ */
++ int osip_negotiation_ctx_set_remote_sdp (osip_negotiation_ctx_t * ctx,
++ sdp_message_t * sdp);
++/**
++ * Get the remote SDP packet associated to this negotiation.
++ * @param ctx The element to work on.
++ */
++ sdp_message_t *osip_negotiation_ctx_get_remote_sdp (osip_negotiation_ctx_t *
++ ctx);
++
++
++/**
++ * Structure for storing the global configuration management.
++ * The information you store here is used when computing a
++ * remote SDP packet to build a compliant answer.
++ * The main objectives is to:
++ * * automaticly refuse unknown media.
++ * * accept some of the known media.
++ * * make sure the SDP answer match the SDP offer.
++ * * simplify the SDP offer/answer model, as all unknown media
++ * are refused without any indication to the application layer.
++ * * In any case, you can still modify the entire SDP packet after
++ * a negotiation if you are not satisfied by the negotiation result.
++ * @var osip_negotiation_t
++ */
++ typedef struct osip_negotiation osip_negotiation_t;
++
++/**
++ * Structure for storing the global configuration management.
++ * @struct osip_negotiation
++ */
++ struct osip_negotiation
++ {
++
++ char *o_username; /**< username */
++ char *o_session_id; /**< session identifier */
++ char *o_session_version; /**< session version */
++ char *o_nettype; /**< Network Type */
++ char *o_addrtype; /**< Address type */
++ char *o_addr; /**< Address */
++
++ char *c_nettype; /**< Network Type */
++ char *c_addrtype; /**< Address Type */
++ char *c_addr; /**< Address */
++ char *c_addr_multicast_ttl; /**< TTL value for multicast address */
++ char *c_addr_multicast_int; /**< Nb of address for multicast */
++
++ osip_list_t *audio_codec; /**< supported audio codec */
++ osip_list_t *video_codec; /**< supported video codec */
++ osip_list_t *other_codec; /**< supported application */
++
++ int (*fcn_set_info) (void *, sdp_message_t *); /**< callback for info */
++ int (*fcn_set_uri) (void *, sdp_message_t *); /**< callback for uri */
++
++ int (*fcn_set_emails) (void *, sdp_message_t *); /**< callback for email */
++ int (*fcn_set_phones) (void *, sdp_message_t *); /**< callback for phones */
++ int (*fcn_set_attributes) (void *, sdp_message_t *, int); /**< callback for attr */
++ int (*fcn_accept_audio_codec) (void *, char *, char *, int, char *); /**< callback to accept audio codec during negotiation */
++ int (*fcn_accept_video_codec) (void *, char *, char *, int, char *); /**< callback to accept video codec during negotiation */
++ int (*fcn_accept_other_codec) (void *, char *, char *, char *, char *); /**< callback to accept application during negotiation */
++ char *(*fcn_get_audio_port) (void *, int); /**< get port for audio stream */
++ char *(*fcn_get_video_port) (void *, int); /**< get port for video stream */
++ char *(*fcn_get_other_port) (void *, int); /**< get port for app stream */
++
++ };
++
++
++/**
++ * Initialise (and Allocate) a sdp_config element (this element is global).
++ * Stores the initialized structure to conf_out.
++ */
++ int osip_negotiation_init (osip_negotiation_t ** conf_out);
++/**
++ * Free resource stored by a sdp_config element.
++ * This method must be called once when the application is stopped.
++ */
++ void osip_negotiation_free (osip_negotiation_t * conf);
++
++/**
++ * Set the local username ('o' field) of all local SDP packet.
++ * @param tmp The username.
++ */
++ int osip_negotiation_set_o_username (osip_negotiation_t *, char *tmp);
++/**
++ * Set the local session id ('o' field) of all local SDP packet.
++ * WARNING: this field should be updated for each new SDP packet?
++ * @param tmp The session id.
++ */
++ int osip_negotiation_set_o_session_id (osip_negotiation_t *, char *tmp);
++/**
++ * Set the local session version ('o' field) of all local SDP packet.
++ * WARNING: this field should be updated for each new SDP packet?
++ * @param tmp The session version.
++ */
++ int osip_negotiation_set_o_session_version (osip_negotiation_t *, char *tmp);
++/**
++ * Set the local network type ('o' field) of all local SDP packet.
++ * @param tmp The network type.
++ */
++ int osip_negotiation_set_o_nettype (osip_negotiation_t *, char *tmp);
++/**
++ * Set the local address type ('o' field) of all local SDP packet.
++ * @param tmp The address type.
++ */
++ int osip_negotiation_set_o_addrtype (osip_negotiation_t *, char *tmp);
++/**
++ * Set the local IP address ('o' field) of all local SDP packet.
++ * @param tmp The IP address.
++ */
++ int osip_negotiation_set_o_addr (osip_negotiation_t *, char *tmp);
++
++/**
++ * Set the local network type ('c' field) of all local SDP packet.
++ * @param tmp The network type.
++ */
++ int osip_negotiation_set_c_nettype (osip_negotiation_t *, char *tmp);
++/**
++ * Set the local address type ('c' field) of all local SDP packet.
++ * @param tmp The address type.
++ */
++ int osip_negotiation_set_c_addrtype (osip_negotiation_t *, char *tmp);
++/**
++ * Set the local IP address ('c' field) of all local SDP packet.
++ * @param tmp The IP address.
++ */
++ int osip_negotiation_set_c_addr (osip_negotiation_t *, char *tmp);
++/**
++ * Set the local ttl for multicast address ('c' field) of all local SDP packet.
++ * @param tmp The ttl for multicast address.
++ */
++ int osip_negotiation_set_c_addr_multicast_ttl (osip_negotiation_t *, char *tmp);
++/**
++ * Set the local int for multicast address ('c' field) of all local SDP packet.
++ * @param tmp The int for multicast address.
++ */
++ int osip_negotiation_set_c_addr_multicast_int (osip_negotiation_t *, char *tmp);
++
++/**
++ * Add a supported audio codec.
++ * Those codecs will be accepted as long as you return 0 when
++ * the callback 'fcn_accept_audio_codec' is called with the specific payload.
++ * @param payload The payload.
++ * @param number_of_port The number of port (channel) for this codec.
++ * @param proto The protocol.
++ * @param c_nettype The network type in the 'c' field.
++ * @param c_addrtype The address type in the 'c' field.
++ * @param c_addr The address in the 'c' field.
++ * @param c_addr_multicast_ttl The ttl for multicast address in the 'c' field.
++ * @param c_addr_multicast_int The int for multicast address in the 'c' field.
++ * @param a_rtpmap The rtpmap attribute in the 'a' field.
++ */
++ int osip_negotiation_add_support_for_audio_codec (osip_negotiation_t *,
++ char *payload,
++ char *number_of_port,
++ char *proto,
++ char *c_nettype,
++ char *c_addrtype,
++ char *c_addr,
++ char
++ *c_addr_multicast_ttl,
++ char
++ *c_addr_multicast_int,
++ char *a_rtpmap);
++/**
++ * Add a supported video codec.
++ * Those codecs will be accepted as long as you return 0 when
++ * the callback 'fcn_accept_video_codec' is called with the specific payload.
++ * @param payload The payload.
++ * @param number_of_port The number of port (channel) for this codec.
++ * @param proto The protocol.
++ * @param c_nettype The network type in the 'c' field.
++ * @param c_addrtype The address type in the 'c' field.
++ * @param c_addr The address in the 'c' field.
++ * @param c_addr_multicast_ttl The ttl for multicast address in the 'c' field.
++ * @param c_addr_multicast_int The int for multicast address in the 'c' field.
++ * @param a_rtpmap The rtpmap attribute in the 'a' field.
++ */
++ int osip_negotiation_add_support_for_video_codec (osip_negotiation_t *,
++ char *payload,
++ char *number_of_port,
++ char *proto,
++ char *c_nettype,
++ char *c_addrtype,
++ char *c_addr,
++ char
++ *c_addr_multicast_ttl,
++ char
++ *c_addr_multicast_int,
++ char *a_rtpmap);
++/**
++ * Add a supported (non-audio and non-video) codec.
++ * Those codecs will be accepted as long as you return 0 when
++ * the callback 'fcn_accept_other_codec' is called with the specific payload.
++ * @param payload The payload.
++ * @param number_of_port The number of port (channel) for this codec.
++ * @param proto The protocol.
++ * @param c_nettype The network type in the 'c' field.
++ * @param c_addrtype The address type in the 'c' field.
++ * @param c_addr The address in the 'c' field.
++ * @param c_addr_multicast_ttl The ttl for multicast address in the 'c' field.
++ * @param c_addr_multicast_int The int for multicast address in the 'c' field.
++ * @param a_rtpmap The rtpmap attribute in the 'a' field.
++ */
++ int osip_negotiation_add_support_for_other_codec (osip_negotiation_t *,
++ char *payload,
++ char *number_of_port,
++ char *proto,
++ char *c_nettype,
++ char *c_addrtype,
++ char *c_addr,
++ char
++ *c_addr_multicast_ttl,
++ char
++ *c_addr_multicast_int,
++ char *a_rtpmap);
++
++#ifndef DOXYGEN
++/**
++ * Free resource in the global sdp_config..
++ */
++ int osip_negotiation_remove_audio_payloads (osip_negotiation_t * config);
++/**
++ * Free resource in the global sdp_config..
++ */
++ int osip_negotiation_remove_video_payloads (osip_negotiation_t * config);
++/**
++ * Free resource in the global sdp_config..
++ */
++ int osip_negotiation_remove_other_payloads (osip_negotiation_t * config);
++#endif
++
++/**
++ * Set the callback for setting info ('i' field) in a local SDP packet.
++ * This callback is called once each time we need an 'i' field.
++ * @param fcn The callback.
++ */
++ int osip_negotiation_set_fcn_set_info (osip_negotiation_t *,
++ int (*fcn) (osip_negotiation_ctx_t *,
++ sdp_message_t *));
++/**
++ * Set the callback for setting a URI ('u' field) in a local SDP packet.
++ * This callback is called once each time we need an 'u' field.
++ * @param fcn The callback.
++ */
++ int osip_negotiation_set_fcn_set_uri (osip_negotiation_t *,
++ int (*fcn) (osip_negotiation_ctx_t *,
++ sdp_message_t *));
++/**
++ * Set the callback for setting an email ('e' field) in a local SDP packet.
++ * This callback is called once each time we need an 'e' field.
++ * @param fcn The callback.
++ */
++ int osip_negotiation_set_fcn_set_emails (osip_negotiation_t *,
++ int (*fcn) (osip_negotiation_ctx_t
++ *, sdp_message_t *));
++/**
++ * Set the callback for setting a phone ('p' field) in a local SDP packet.
++ * This callback is called once each time we need an 'p' field.
++ * @param fcn The callback.
++ */
++ int osip_negotiation_set_fcn_set_phones (osip_negotiation_t *,
++ int (*fcn) (osip_negotiation_ctx_t
++ *, sdp_message_t *));
++/**
++ * Set the callback for setting an attribute ('a' field) in a local SDP packet.
++ * This callback is called once each time we need an 'a' field.
++ * @param fcn The callback.
++ */
++ int
++ osip_negotiation_set_fcn_set_attributes (osip_negotiation_t *,
++ int (*fcn)
++ (osip_negotiation_ctx_t *,
++ sdp_message_t *, int));
++/**
++ * Set the callback used to accept a codec during a negotiation.
++ * This callback is called once each time we need to accept a codec.
++ * @param fcn The callback.
++ */
++ int
++ osip_negotiation_set_fcn_accept_audio_codec (osip_negotiation_t *,
++ int (*fcn)
++ (osip_negotiation_ctx_t *,
++ char *, char *, int, char *));
++/**
++ * Set the callback used to accept a codec during a negotiation.
++ * This callback is called once each time we need to accept a codec.
++ * @param fcn The callback.
++ */
++ int
++ osip_negotiation_set_fcn_accept_video_codec (osip_negotiation_t *,
++ int (*fcn)
++ (osip_negotiation_ctx_t *,
++ char *, char *, int, char *));
++/**
++ * Set the callback used to accept a codec during a negotiation.
++ * This callback is called once each time we need to accept a codec.
++ * @param fcn The callback.
++ */
++ int
++ osip_negotiation_set_fcn_accept_other_codec (osip_negotiation_t *,
++ int (*fcn)
++ (osip_negotiation_ctx_t *,
++ char *, char *, char *, char *));
++/**
++ * Set the callback for setting the port number ('m' field) in a local SDP packet.
++ * This callback is called once each time a 'm' line is accepted.
++ * @param fcn The callback.
++ */
++ int osip_negotiation_set_fcn_get_audio_port (osip_negotiation_t *,
++ char
++ *(*fcn) (osip_negotiation_ctx_t
++ *, int));
++/**
++ * Set the callback for setting the port number ('m' field) in a local SDP packet.
++ * This callback is called once each time a 'm' line is accepted.
++ * @param fcn The callback.
++ */
++ int osip_negotiation_set_fcn_get_video_port (osip_negotiation_t *,
++ char
++ *(*fcn) (osip_negotiation_ctx_t
++ *, int));
++/**
++ * Set the callback for setting the port number ('m' field) in a local SDP packet.
++ * This callback is called once each time a 'm' line is accepted.
++ * @param fcn The callback.
++ */
++ int osip_negotiation_set_fcn_get_other_port (osip_negotiation_t *,
++ char
++ *(*fcn) (osip_negotiation_ctx_t
++ *, int));
++
++/**
++ * Start the automatic negotiation for a UA
++ * NOTE: You can previously set context->mycontext to point to your
++ * personal context. This way you'll get access to your personal context
++ * in the callback and you can easily take the correct decisions.
++ * After this method is called, the negotiation will happen and
++ * callbacks will be called. You can modify, add, remove SDP fields,
++ * and accept and refuse the codec from your preferred list by using
++ * those callbacks.
++ * Of course, after the negotiation happen, you can modify the
++ * SDP packet if you wish to improve it or just refine some attributes.
++ * @param ctx The context holding the remote SDP offer.
++ */
++ int osip_negotiation_ctx_execute_negotiation (osip_negotiation_t *,
++ osip_negotiation_ctx_t * ctx);
++
++/** Put the SDP message on hold in outgoing invite
++ * @param ctx The element to work on.
++ * @param sdp The sdp message to build.
++ * @param audio_port The port for audio stream.
++ * @param video_port The port for video stream.
++ */
++ int osip_negotiation_sdp_build_offer (osip_negotiation_t *,
++ osip_negotiation_ctx_t * ctx,
++ sdp_message_t ** sdp,
++ char *audio_port, char *video_port);
++/**
++ *@internal
++ */
++ int __osip_negotiation_sdp_build_offer (osip_negotiation_t *,
++ osip_negotiation_ctx_t * ctx,
++ sdp_message_t ** sdp,
++ char *audio_port, char *video_port,
++ char *audio_codec, char *video_codec);
++
++/** Put the SDP message on hold in outgoing invite
++ * @param sdp The sdp message to modify.
++ */
++ int osip_negotiation_sdp_message_put_on_hold (sdp_message_t * sdp);
++
++/** Put the SDP message off hold in outgoing invite
++ * @param sdp The sdp message to modify.
++ */
++ int osip_negotiation_sdp_message_put_off_hold (sdp_message_t * sdp);
++
++/**
++ * @internal
++ * @}
++ */
++
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif /*_SDP_NEGOC_H_ */
--- linphone-base.patch ends here ---
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-ports-bugs
mailing list