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