From 2953c83c4ab6040d07a196d31874737958a4e6e3 Mon Sep 17 00:00:00 2001
From: yanmorin <yanmorin>
Date: Wed, 26 Jul 2006 16:18:07 +0000
Subject: [PATCH] *** empty log message ***

---
 src/eventthread.cpp |   1 +
 src/iaxaccount.cpp  |   2 +-
 src/iaxcall.cpp     | 633 +-------------------------------------------
 src/iaxvoiplink.cpp | 107 +++++++-
 src/iaxvoiplink.h   |   8 +-
 src/sipcall.cpp     | 633 +++++++++++++++++++++++++++++++++++++++++++-
 6 files changed, 744 insertions(+), 640 deletions(-)

diff --git a/src/eventthread.cpp b/src/eventthread.cpp
index dd113bad97..401e2e8948 100644
--- a/src/eventthread.cpp
+++ b/src/eventthread.cpp
@@ -43,3 +43,4 @@ EventThread::run (void)
   }
 }
 
+
diff --git a/src/iaxaccount.cpp b/src/iaxaccount.cpp
index d8b49a5914..7ef9838bcd 100644
--- a/src/iaxaccount.cpp
+++ b/src/iaxaccount.cpp
@@ -88,7 +88,7 @@ IAXAccount::initConfig(Conf::ConfigTree& config)
   std::string type_str("string");
   std::string type_int("int");
   
-  config.addConfigTreeItem(section, Conf::ConfigTreeItem(CONFIG_ACCOUNT_TYPE, "AIX", type_str));
+  config.addConfigTreeItem(section, Conf::ConfigTreeItem(CONFIG_ACCOUNT_TYPE, "IAX", type_str));
   config.addConfigTreeItem(section, Conf::ConfigTreeItem(CONFIG_ACCOUNT_ENABLE,"1", type_int));
   config.addConfigTreeItem(section, Conf::ConfigTreeItem(CONFIG_ACCOUNT_AUTO_REGISTER, "1", type_int));
 }
diff --git a/src/iaxcall.cpp b/src/iaxcall.cpp
index cb3fde0926..bfcd6f8e0f 100644
--- a/src/iaxcall.cpp
+++ b/src/iaxcall.cpp
@@ -1,7 +1,6 @@
 /*
- *  Copyright (C) 2004-2006 Savoir-Faire Linux inc.
+ *  Copyright (C) 2006 Savoir-Faire Linux inc.
  *  Author: Yan Morin <yan.morin@savoirfairelinux.com>
- *  Author : Laurielle Lea <laurielle.lea@savoirfairelinux.com>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -18,636 +17,16 @@
  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#include "sipcall.h"
+#include "iaxcall.h"
 #include "global.h" // for _debug
-#include <sstream> // for media buffer
 
-#define _SENDRECV 0
-#define _SENDONLY 1
-#define _RECVONLY 2
-
-SIPCall::SIPCall(const CallID& id, Call::CallType type) : Call(id, type), 
- _localIPAddress(""), _remoteIPAddress("")  
-{
-  _cid = 0;
-  _did = 0;
-  _tid = 0;
-  _audioCodec = 0;
-  _localAudioPort = 0;
-  _localExternalAudioPort = 0;
-  _remoteAudioPort = 0;
-}
-
-SIPCall::~SIPCall() 
+IAXCall::IAXCall(const CallID& id, Call::CallType type) : Call(id, type), _session(0) 
 {
+	
 }
 
-CodecDescriptorMap& 
-SIPCall::getCodecMap()
+IAXCall::~IAXCall() 
 {
-  return _codecMap;
+  _session = 0; // just to be sure to don't have unknown pointer, do not delete it!
 }
 
-/**
- * Answer incoming call correclty before telling the user
- * @param event eXosip Event
- */
-bool 
-SIPCall::SIPCallInvite(eXosip_event_t *event)
-{
-  if (event->cid < 1 && event->did < 1) {
-    _debug("SIP Failure: Invalid cid and did\n");
-    return false;
-  }
-
-  if (event->request == NULL) {
-    _debug("SIP Failure: No request into the event\n");
-    return false;
-  }
-
-  setCid(event->cid);
-  setDid(event->did);
-  setTid(event->tid);
-
-  setPeerInfoFromRequest(event);
-  
-  sdp_message_t* remote_sdp = getRemoteSDPFromRequest(event);
-  if (remote_sdp == 0) {
-    return false;
-  }
-
-  sdp_media_t* remote_med = getRemoteMedia(event->tid, remote_sdp);
-  if (remote_med == 0) {
-    sdp_message_free (remote_sdp);
-    return false;
-  }
-
-  if (!setRemoteAudioFromSDP(remote_med, remote_sdp)) {
-    _debug("SIP Failure: unable to set IP address and port from SDP\n");
-    sdp_message_free (remote_sdp);
-    return false;
-  }
-
-  if (!setAudioCodecFromSDP(remote_med, event->tid)) {
-    sdp_message_free (remote_sdp);
-    return false;
-  }
-
-  osip_message_t *answer = 0;
-  eXosip_lock();
-  _debug("< Building Answer 183\n");
-  if (0 == eXosip_call_build_answer (event->tid, 183, &answer)) {
-    if ( 0 != sdp_complete_message(remote_sdp, answer)) {
-      osip_message_free(answer);
-      // Send 415 Unsupported media type
-      _debug("< Sending Answer 415 : unsupported media type\n");
-      eXosip_call_send_answer (event->tid, 415, NULL);
-    } else {
-
-      sdp_message_t *local_sdp = eXosip_get_sdp_info(answer);
-      sdp_media_t *local_med = NULL;
-      if (local_sdp != NULL) {
-         local_med = eXosip_get_audio_media(local_sdp);
-      }
-      if (local_sdp != NULL && local_med != NULL) {
-        /* search if stream is sendonly or recvonly */
-        int _remote_sendrecv = sdp_analyse_attribute (remote_sdp, remote_med);
-        int _local_sendrecv =  sdp_analyse_attribute (local_sdp, local_med);
-        _debug("            Remote SendRecv: %d\n", _remote_sendrecv);
-        _debug("            Local  SendRecv: %d\n", _local_sendrecv);
-        if (_local_sendrecv == _SENDRECV) {
-          if (_remote_sendrecv == _SENDONLY)      { _local_sendrecv = _RECVONLY; }
-          else if (_remote_sendrecv == _RECVONLY) { _local_sendrecv = _SENDONLY; }
-        }
-        _debug("            Final Local SendRecv: %d\n", _local_sendrecv);
-        sdp_message_free (local_sdp);
-      }
-      _debug("< Sending answer 183\n");
-      if (0 != eXosip_call_send_answer (event->tid, 183, answer)) {
-        _debug("SipCall::newIncomingCall: cannot send 183 progress?\n");
-      }
-    }
-  }
-  eXosip_unlock ();
-
-  sdp_message_free (remote_sdp);
-  return true;
-}
-
-/**
-  * newReinviteCall is called when the IP-Phone user receives a change in the call
-  * it's almost an newIncomingCall but we send a 200 OK
-  * See: 3.7.  Session with re-INVITE (IP Address Change)
-  * @param event eXosip Event
-  * @return true if ok
-  */
-bool 
-SIPCall::SIPCallReinvite(eXosip_event_t *event)
-{
-  if (event->cid < 1 && event->did < 1) {
-    _debug("SIP Failure: Invalid cid and did\n");
-    return false;
-  }
-
-  if (event->request == NULL) {
-    _debug("SIP Failure: No request into the event\n");
-    return false;
-  }
-
-  setCid(event->cid);
-  setDid(event->did);
-  setTid(event->tid);
-
-  setPeerInfoFromRequest(event);
-
-  sdp_message_t* remote_sdp = getRemoteSDPFromRequest(event);
-  if (remote_sdp == 0) {
-    return false;
-  }
-
-  sdp_media_t* remote_med = getRemoteMedia(event->tid, remote_sdp);
-  if (remote_med == 0) {
-    sdp_message_free (remote_sdp);
-    return false;
-  }
-
-  if (!setRemoteAudioFromSDP(remote_med, remote_sdp)) {
-    _debug("SIP Failure: unable to set IP address and port from SDP\n");
-    sdp_message_free (remote_sdp);
-    return false;
-  }
-
-  if (!setAudioCodecFromSDP(remote_med, event->tid)) {
-    sdp_message_free (remote_sdp);
-    return false;
-  }
-
-  osip_message_t *answer = 0;
-  eXosip_lock();
-  _debug("< Building Answer 200\n");
-  if (0 == eXosip_call_build_answer (event->tid, 200, &answer)) {
-    if ( 0 != sdp_complete_message(remote_sdp, answer)) {
-      osip_message_free(answer);
-      // Send 415 Unsupported media type
-      eXosip_call_send_answer (event->tid, 415, NULL);
-      _debug("< Sending Answer 415\n");
-    } else {
-
-      sdp_message_t *local_sdp = eXosip_get_sdp_info(answer);
-      sdp_media_t *local_med = NULL;
-      if (local_sdp != NULL) {
-         local_med = eXosip_get_audio_media(local_sdp);
-      }
-      if (local_sdp != NULL && local_med != NULL) {
-        /* search if stream is sendonly or recvonly */
-        int _remote_sendrecv = sdp_analyse_attribute (remote_sdp, remote_med);
-        int _local_sendrecv =  sdp_analyse_attribute (local_sdp, local_med);
-        _debug("            Remote SendRecv: %d\n", _remote_sendrecv);
-        _debug("            Local  SendRecv: %d\n", _local_sendrecv);
-        if (_local_sendrecv == _SENDRECV) {
-          if (_remote_sendrecv == _SENDONLY)      { _local_sendrecv = _RECVONLY; }
-          else if (_remote_sendrecv == _RECVONLY) { _local_sendrecv = _SENDONLY; }
-        }
-        _debug("            Final Local SendRecv: %d\n", _local_sendrecv);
-        sdp_message_free (local_sdp);
-      }
-      _debug("< Sending answer 200\n");
-      if (0 != eXosip_call_send_answer (event->tid, 200, answer)) {
-        _debug("SipCall::newIncomingCall: cannot send 200 OK?\n");
-      }
-    }
-  }
-  eXosip_unlock ();
-  sdp_message_free (remote_sdp);
-  return true;
-}
-
-  /**
-   * Peer answered to a call (on hold or not)
-   * @param event eXosip Event
-   * @return true if ok
-   */
-bool 
-SIPCall::SIPCallAnswered(eXosip_event_t *event)
-{
-  if (event->cid < 1 && event->did < 1) {
-    _debug("SIP Failure: Invalid cid and did\n");
-    return false;
-  }
-
-  if (event->request == NULL) {
-    _debug("SIP Failure: No request into the event\n");
-    return false;
-  }
-
-  setCid(event->cid);
-  setDid(event->did);
-
-  //setPeerInfoFromResponse()
-
-  eXosip_lock ();
-  {
-    osip_message_t *ack = NULL;
-    int i;
-    i = eXosip_call_build_ack (event->did, &ack);
-    if (i != 0) {
-      _debug("SipCall::answeredCall: Cannot build ACK for call!\n");
-    } else {
-      sdp_message_t *local_sdp = NULL;
-      sdp_message_t *remote_sdp = NULL;
-
-      if (event->request != NULL && event->response != NULL) {
-        local_sdp = eXosip_get_sdp_info (event->request);
-        remote_sdp = eXosip_get_sdp_info (event->response);
-      }
-      if (local_sdp == NULL && remote_sdp != NULL) {
-        /* sdp in ACK */
-        i = sdp_complete_message (remote_sdp, ack);
-        if (i != 0) {
-            _debug("SipCall::answeredCall: Cannot complete ACK with sdp body?!\n");
-        }
-      }
-      sdp_message_free (local_sdp);
-      sdp_message_free (remote_sdp);
-
-      _debug("< Send ACK\n");
-      eXosip_call_send_ack (event->did, ack);
-    }
-  }
-  eXosip_unlock ();
-  return true;  
-}
-  /**
-   * We retreive final SDP info if they changed
-   * @param event eXosip Event
-   * @return true if ok (change / no change) or false on error
-   */
-bool 
-SIPCall::SIPCallAnsweredWithoutHold(eXosip_event_t *event)
-{
-  if (event->response == NULL || event->request  == NULL) { return false; }
-  
-  eXosip_lock();
-  sdp_message_t *remote_sdp = eXosip_get_sdp_info (event->response);
-  eXosip_unlock();
-  if (remote_sdp == NULL) {
-    _debug("SIP Failure: no remote sdp\n");
-    sdp_message_free(remote_sdp);
-    return false;
-  }
-
-  sdp_media_t *remote_med = getRemoteMedia(event->tid, remote_sdp);
-  if (remote_med==NULL) {
-    sdp_message_free(remote_sdp);
-    return false;
-  }
-  if ( ! setRemoteAudioFromSDP(remote_med, remote_sdp) ) {
-    sdp_message_free(remote_sdp);
-    return false;
-  }
-
-  char *tmp = (char *) osip_list_get (remote_med->m_payloads, 0);
-
-  setAudioCodec(0);
-  if (tmp != NULL) {
-    int payload = atoi (tmp);
-    _debug("            Remote Payload: %d\n", payload);
-    setAudioCodec(_codecMap.getCodec((CodecType)payload)); // codec builder for the mic
-  }
-
-/*
-    // search if stream is sendonly or recvonly
-    _remote_sendrecv = sdp_analyse_attribute (remote_sdp, remote_med);
-    _local_sendrecv = sdp_analyse_attribute (local_sdp, local_med);
-    if (_local_sendrecv == _SENDRECV) {
-      if (_remote_sendrecv == _SENDONLY)
-          _local_sendrecv = _RECVONLY;
-      else if (_remote_sendrecv == _RECVONLY)
-          _local_sendrecv = _SENDONLY;
-    }
-  _debug("            Remote Sendrecv: %d\n", _remote_sendrecv);
-  _debug("            Local Sendrecv: %d\n", _local_sendrecv);
-*/
-  sdp_message_free (remote_sdp);
-  return true;
-}
-
-const std::string& 
-SIPCall::getLocalIp()
-{
-  ost::MutexLock m(_callMutex);  
-  return _localIPAddress;
-}
-
-unsigned int 
-SIPCall::getLocalAudioPort()
-{
-  ost::MutexLock m(_callMutex);  
-  return _localAudioPort;
-}
-
-unsigned int 
-SIPCall::getRemoteAudioPort()
-{
-  ost::MutexLock m(_callMutex);  
-  return _remoteAudioPort;
-}
-
-const std::string& 
-SIPCall::getRemoteIp()
-{
-  ost::MutexLock m(_callMutex);  
-  return _remoteIPAddress;
-}
-
-AudioCodec* 
-SIPCall::getAudioCodec()
-{
-  ost::MutexLock m(_callMutex);  
-  return _audioCodec;  
-}
-
-void 
-SIPCall::setAudioStart(bool start)
-{
-  ost::MutexLock m(_callMutex);  
-  _audioStarted = start;  
-}
-
-bool 
-SIPCall::isAudioStarted()
-{
-  ost::MutexLock m(_callMutex);  
-  return _audioStarted;
-}
-
-  //TODO: humm?
-int 
-SIPCall::sdp_complete_message(sdp_message_t * remote_sdp, osip_message_t * msg)
-{
-  // Format port to a char*
-  if (remote_sdp == NULL) {
-    _debug("SipCall::sdp_complete_message: No remote SDP body found for call\n");
-    return -1;
-  }
-  if (msg == NULL) {
-    _debug("SipCall::sdp_complete_message: No message to complete\n");
-    return -1;
-  }
-
-  std::ostringstream media;
-
-  // for each medias
-  int iMedia = 0;
-  char *tmp = NULL;
-  while (!osip_list_eol(remote_sdp->m_medias, iMedia)) {
-    sdp_media_t *remote_med = (sdp_media_t *)osip_list_get(remote_sdp->m_medias, iMedia);
-    if (remote_med == 0) { continue; }
-
-    if (0 != osip_strcasecmp (remote_med->m_media, "audio")) {
-      // if this is not an "audio" media, we set it to 0
-      media << "m=" << remote_med->m_media << " 0 " << remote_med->m_proto << " \r\n";
-    } else {
-      std::ostringstream listCodec;
-      std::ostringstream listRtpMap;
-
-      // search for compatible codec: foreach payload
-      int iPayload = 0;
-      while (!osip_list_eol(remote_med->m_payloads, iPayload)) {
-        tmp = (char *)osip_list_get(remote_med->m_payloads, iPayload);
-        if (tmp!=NULL) {
-          int payload = atoi(tmp);
-          AudioCodec* audiocodec = _codecMap.getCodec((CodecType)payload);
-          if (audiocodec!=0 && audiocodec->isActive()) {
-            listCodec << payload << " ";
-            listRtpMap << "a=rtpmap: " << payload << " " << audiocodec->getCodecName() << "/" << audiocodec->getClockRate();
-            if ( audiocodec->getChannel() != 1) {
-              listRtpMap << "/" << audiocodec->getChannel();
-            }
-            listRtpMap << "\r\n";
-          }
-        }
-        iPayload++;
-      }
-      if (listCodec.str().empty()) {
-        media << "m=" << remote_med->m_media << " 0 " << remote_med->m_proto << " \r\n";
-      } else {
-        // we add the media line + a=rtpmap list
-        media << "m=" << remote_med->m_media << " " << getLocalExternAudioPort() << " RTP/AVP " << listCodec.str() << "\r\n";
-        media << listRtpMap.str();
-      }
-    }
-    iMedia++;
-  }
-  char buf[4096];
-  snprintf (buf, 4096,
-    "v=0\r\n"
-    "o=user 0 0 IN IP4 %s\r\n"
-    "s=session\r\n"
-    "c=IN IP4 %s\r\n"
-    "t=0 0\r\n"
-    "%s\n", getLocalIp().c_str(), getLocalIp().c_str(), media.str().c_str());
-
-  osip_message_set_body (msg, buf, strlen (buf));
-  osip_message_set_content_type (msg, "application/sdp");
-  _debug("          sdp: %s", buf);
-  return 0;
-}
-
-
-  // TODO: hum???
-int 
-SIPCall::sdp_analyse_attribute (sdp_message_t * sdp, sdp_media_t * med)
-{
-  int pos;
-  int pos_media;
-
-  /* test media attributes */
-  pos = 0;
-  while (!osip_list_eol (med->a_attributes, pos)) {
-      sdp_attribute_t *at;
-
-      at = (sdp_attribute_t *) osip_list_get (med->a_attributes, pos);
-      if (at->a_att_field != NULL && 
-      0 == strcmp (at->a_att_field, "sendonly")) {
-      return _SENDONLY;
-      } else if (at->a_att_field != NULL &&
-                0 == strcmp (at->a_att_field, "recvonly")) {
-          return _RECVONLY;
-      } else if (at->a_att_field != NULL &&
-                0 == strcmp (at->a_att_field, "sendrecv")) {
-          return _SENDRECV;
-      }
-      pos++;
-  }
-
-  /* test global attributes */
-  pos_media = -1;
-  pos = 0;
-  while (!osip_list_eol (sdp->a_attributes, pos)) {
-      sdp_attribute_t *at;
-
-      at = (sdp_attribute_t *) osip_list_get (sdp->a_attributes, pos);
-      if (at->a_att_field != NULL && 
-      0 == strcmp (at->a_att_field, "sendonly")) {
-          return _SENDONLY;
-      } else if (at->a_att_field != NULL &&
-                0 == strcmp (at->a_att_field, "recvonly")) {
-          return _RECVONLY;
-      } else if (at->a_att_field != NULL &&
-                0 == strcmp (at->a_att_field, "sendrecv")) {
-          return _SENDRECV;
-      }
-      pos++;
-  }
-
-  return _SENDRECV;
-}
-
-bool 
-SIPCall::setPeerInfoFromRequest(eXosip_event_t *event)
-{
-  // event->request should not be NULL!
-  char remote_uri[256] = "";
-  std::string name("");
-  std::string number("");
-
-  char *tmp = NULL;
-  osip_from_to_str(event->request->from, &tmp);
-  if (tmp != NULL) {
-    snprintf (remote_uri, 255, "%s", tmp);
-    remote_uri[255] = '\0';
-    osip_free (tmp);
-
-    // Get the name/number
-    osip_from_t *from;
-    osip_from_init(&from);
-    osip_from_parse(from, remote_uri);
-    char *tmpname = osip_from_get_displayname(from);
-    if ( tmpname != NULL ) {
-      name = tmpname;
-    }
-    osip_uri_t* url = osip_from_get_url(from); 
-    if ( url != NULL && url->username != NULL) {
-      number = url->username;
-    }
-    osip_from_free(from);
-  }
-
-  _debug("            Name: %s\n", name.c_str());
-  _debug("            Number: %s\n", number.c_str());
-  _debug("            Remote URI: %s\n", remote_uri);
-
-  setPeerName(name);
-  setPeerNumber(number);  
-  return true;
-}
-
-sdp_message_t* 
-SIPCall::getRemoteSDPFromRequest(eXosip_event_t *event)
-{
-  // event->request should not be null!
-  /* negotiate payloads */
-  sdp_message_t *remote_sdp = NULL;
-  if (event->request != NULL) {
-    eXosip_lock();
-    remote_sdp = eXosip_get_sdp_info (event->request);
-    eXosip_unlock();
-  }
-  if (remote_sdp == NULL) {
-    _debug("SIP Failure: No SDP into the request\n");
-    _debug("< Sending 400 Bad Request (no SDP)\n");
-    eXosip_lock();
-    eXosip_call_send_answer (event->tid, 400, NULL);
-    eXosip_unlock();
-    return 0;
-  }
-  return remote_sdp;
-}
-
-sdp_media_t* 
-SIPCall::getRemoteMedia(int tid, sdp_message_t* remote_sdp)
-{
-  // Remote Media Port
-  eXosip_lock();
-  sdp_media_t *remote_med = eXosip_get_audio_media(remote_sdp);
-  eXosip_unlock();
-
-  if (remote_med == NULL || remote_med->m_port == NULL) {
-    // no audio media proposed
-    _debug("SIP Failure: unsupported media\n");
-    _debug("< Sending 415 Unsupported media type\n");
-    eXosip_lock();
-    eXosip_call_send_answer (tid, 415, NULL);
-    eXosip_unlock();
-    sdp_message_free (remote_sdp);
-    return 0;
-  }
-  return remote_med;
-}
-
-bool 
-SIPCall::setRemoteAudioFromSDP(sdp_media_t* remote_med, sdp_message_t* remote_sdp)
-{
-  // Remote Media IP
-  eXosip_lock();
-  sdp_connection_t *conn = eXosip_get_audio_connection(remote_sdp);
-  eXosip_unlock();
-  if (conn != NULL && conn->c_addr != NULL) {
-    char _remote_sdp_audio_ip[50] = "";
-    snprintf (_remote_sdp_audio_ip, 49, "%s", conn->c_addr);
-    _remote_sdp_audio_ip[49] = '\0';
-    _debug("            Remote Audio IP: %s\n", _remote_sdp_audio_ip);
-    setRemoteIP(_remote_sdp_audio_ip);
-    if (_remote_sdp_audio_ip[0] == '\0') {
-      setRemoteAudioPort(0);
-      return false;
-    }
-  }
-
-  // Remote port
-  int _remote_sdp_audio_port = atoi(remote_med->m_port);
-  _debug("            Remote Audio Port: %d\n", _remote_sdp_audio_port);
-  setRemoteAudioPort(_remote_sdp_audio_port);
-
-  if (_remote_sdp_audio_port == 0) {
-    return false;
-  }
-  return true;
-}
-
-bool 
-SIPCall::setAudioCodecFromSDP(sdp_media_t* remote_med, int tid)
-{
-  // Remote Payload
-  char *tmp = NULL;
-  int pos = 0;
-  while (!osip_list_eol (remote_med->m_payloads, pos)) {
-    tmp = (char *) osip_list_get (remote_med->m_payloads, pos);
-    if (tmp != NULL ) {
-      int payload = atoi(tmp);
-      // stop if we find a correct codec
-      if (0 != _codecMap.getCodec((CodecType)payload)){
-          break;
-      }
-    }
-    tmp = NULL;
-    pos++;
-  }
-
-  setAudioCodec(0);
-  if (tmp != NULL) {
-    int payload = atoi (tmp);
-    _debug("            Payload: %d\n", payload);
-    setAudioCodec(_codecMap.getCodec((CodecType)payload)); // codec builder for the mic
-  }
-  if (getAudioCodec() == 0) {
-    _debug("SIPCall Failure: Unable to set codec\n");
-    _debug("< Sending 415 Unsupported media type\n");
-    eXosip_lock();
-    eXosip_call_send_answer(tid, 415, NULL);
-    eXosip_unlock();
-    return false;
-  }
-  return true;
-}
diff --git a/src/iaxvoiplink.cpp b/src/iaxvoiplink.cpp
index b02732d3cc..3a5a0d8cd8 100644
--- a/src/iaxvoiplink.cpp
+++ b/src/iaxvoiplink.cpp
@@ -28,12 +28,14 @@ IAXVoIPLink::IAXVoIPLink(const AccountID& accountID)
  : VoIPLink(accountID)
 {
   _evThread = new EventThread(this);
+  _regSession = 0;
 }
 
 
 IAXVoIPLink::~IAXVoIPLink()
 {
   delete _evThread; _evThread = 0;
+  _regSession = 0; // shall not delete it
   terminate();
 }
 
@@ -53,6 +55,8 @@ IAXVoIPLink::init()
     _debug("IAX Info: listening on port %d\n", port);
     _localPort = port;
     returnValue = true;
+
+    _evThread->start();
   }
   return returnValue;
 }
@@ -75,17 +79,58 @@ IAXVoIPLink::getEvent()
     call = iaxFindCallBySession(event->session);
     if (call!=0) {
 	iaxHandleCallEvent(event, call);
+    } else if (event->session != 0 && event->session == _regSession) {
+    	// in iaxclient, there is many session handling, here, only one
+	iaxHandleRegReply(event);
+    } else {
+    	switch(e->etype) {
+		case IAX_EVENT_REGACK:
+		case IAX_EVENT_REGREJ:
+			_debug("Unknown IAX Registration Event\n");
+		break;
+
+		case IAX_EVENT_REGREQ:
+			_debug("Registration by a peer, don't allow it\n");
+		break;
+		case IAX_EVENT_CONNECT: // new call
+			// New incoming call!	
+		break;
+
+		case IAX_EVENT_TIMEOUT: // timeout for an unknown session
+			
+		break;
+
+		default: 
+			_debug("Unknown event type: %d\n", event->type);
+	}
     }
-    return;
+    iax_event_free(event);
   }
-  iax_event_free(event);
-  // thread wait 5 second
-  // unlock mutex
+  // unlock mutex here
+
+  //iaxRefreshRegistrations();
+
+  // thread wait 5 millisecond
+  _evThread->sleep(5);
 }
 
 bool
 IAXVoIPLink::setRegister() 
 {
+  if (_regSession==0) {
+    // lock
+
+    _regSession = iax_session_new();
+
+    if (!_regSession) {
+      _debug("error when generating new session for register");
+    } else {
+      // refresh
+      // last reg
+    }
+
+	// unlock
+  }
   return false;
 }
 
@@ -116,5 +161,57 @@ IAXVoIPLink::iaxFindCallBySession(struct iax_session* session)
 void
 IAXVoIPLink::iaxHandleCallEvent(iax_event* event, IAXCall* call) 
 {
-  
+  // call should not be 0
+  // note activity?
+  //
+  switch(event->type) {
+    case IAX_EVENT_HANGUP:
+    break;
+
+    case IAX_EVENT_REJECT:
+    break;
+
+    case IAX_EVENT_ACCEPT:
+    break;
+    
+    case IAX_EVENT_ANSWER:
+    break;
+    
+    case IAX_EVENT_BUSY:
+    break;
+    
+    case IAX_EVENT_VOICE:
+    break;
+    
+    case IAX_EVENT_TEXT:
+    break;
+    
+    case IAX_EVENT_RINGA:
+    break;
+    
+    case IAX_EVENT_PONG:
+    break;
+    
+    case IAX_EVENT_URL:
+    break;
+    
+    case IAX_EVENT_CNG:
+    break;
+    
+    case IAX_EVENT_TIMEOUT:
+    break;
+    
+    case IAX_EVENT_TRANSFER:
+    break;
+    
+    default:
+      _debug("Unknown event type: %d\n", event->type);
+    
+  }
+}
+
+void
+IAXVoIPLink::iaxHandleRegReply(iax_event* event) 
+{
+  // use _regSession here, should be equal to event->session;
 }
diff --git a/src/iaxvoiplink.h b/src/iaxvoiplink.h
index c0329a7401..47d0d3e227 100644
--- a/src/iaxvoiplink.h
+++ b/src/iaxvoiplink.h
@@ -63,7 +63,7 @@ private:
    * @param session an iax_session valid pointer
    * @return iaxcall or 0 if not found
    */
-  IAXCall* iaxFindCallBySession(struct iax_session *session);
+  IAXCall* iaxFindCallBySession(struct iax_session* session);
 
   /**
    * Handle IAX Event for a call
@@ -72,8 +72,14 @@ private:
    */
   void iaxHandleCallEvent(iax_event* event, IAXCall* call);
 
+  /**
+   * Handle IAX Registration Reply event
+   * @param event An iax_event pointer
+   */
+  void iaxHandleRegReply(iax_event* event);
 
   EventThread* _evThread;
+  struct iax_session* _regSession;
 };
 
 #endif
diff --git a/src/sipcall.cpp b/src/sipcall.cpp
index bfcd6f8e0f..cb3fde0926 100644
--- a/src/sipcall.cpp
+++ b/src/sipcall.cpp
@@ -1,6 +1,7 @@
 /*
- *  Copyright (C) 2006 Savoir-Faire Linux inc.
+ *  Copyright (C) 2004-2006 Savoir-Faire Linux inc.
  *  Author: Yan Morin <yan.morin@savoirfairelinux.com>
+ *  Author : Laurielle Lea <laurielle.lea@savoirfairelinux.com>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -17,16 +18,636 @@
  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#include "iaxcall.h"
+#include "sipcall.h"
 #include "global.h" // for _debug
+#include <sstream> // for media buffer
 
-IAXCall::IAXCall(const CallID& id, Call::CallType type) : Call(id, type), _session(0) 
+#define _SENDRECV 0
+#define _SENDONLY 1
+#define _RECVONLY 2
+
+SIPCall::SIPCall(const CallID& id, Call::CallType type) : Call(id, type), 
+ _localIPAddress(""), _remoteIPAddress("")  
+{
+  _cid = 0;
+  _did = 0;
+  _tid = 0;
+  _audioCodec = 0;
+  _localAudioPort = 0;
+  _localExternalAudioPort = 0;
+  _remoteAudioPort = 0;
+}
+
+SIPCall::~SIPCall() 
 {
-	
 }
 
-IAXCall::~IAXCall() 
+CodecDescriptorMap& 
+SIPCall::getCodecMap()
 {
-  _session = 0; // just to be sure to don't have unknown pointer, do not delete it!
+  return _codecMap;
 }
 
+/**
+ * Answer incoming call correclty before telling the user
+ * @param event eXosip Event
+ */
+bool 
+SIPCall::SIPCallInvite(eXosip_event_t *event)
+{
+  if (event->cid < 1 && event->did < 1) {
+    _debug("SIP Failure: Invalid cid and did\n");
+    return false;
+  }
+
+  if (event->request == NULL) {
+    _debug("SIP Failure: No request into the event\n");
+    return false;
+  }
+
+  setCid(event->cid);
+  setDid(event->did);
+  setTid(event->tid);
+
+  setPeerInfoFromRequest(event);
+  
+  sdp_message_t* remote_sdp = getRemoteSDPFromRequest(event);
+  if (remote_sdp == 0) {
+    return false;
+  }
+
+  sdp_media_t* remote_med = getRemoteMedia(event->tid, remote_sdp);
+  if (remote_med == 0) {
+    sdp_message_free (remote_sdp);
+    return false;
+  }
+
+  if (!setRemoteAudioFromSDP(remote_med, remote_sdp)) {
+    _debug("SIP Failure: unable to set IP address and port from SDP\n");
+    sdp_message_free (remote_sdp);
+    return false;
+  }
+
+  if (!setAudioCodecFromSDP(remote_med, event->tid)) {
+    sdp_message_free (remote_sdp);
+    return false;
+  }
+
+  osip_message_t *answer = 0;
+  eXosip_lock();
+  _debug("< Building Answer 183\n");
+  if (0 == eXosip_call_build_answer (event->tid, 183, &answer)) {
+    if ( 0 != sdp_complete_message(remote_sdp, answer)) {
+      osip_message_free(answer);
+      // Send 415 Unsupported media type
+      _debug("< Sending Answer 415 : unsupported media type\n");
+      eXosip_call_send_answer (event->tid, 415, NULL);
+    } else {
+
+      sdp_message_t *local_sdp = eXosip_get_sdp_info(answer);
+      sdp_media_t *local_med = NULL;
+      if (local_sdp != NULL) {
+         local_med = eXosip_get_audio_media(local_sdp);
+      }
+      if (local_sdp != NULL && local_med != NULL) {
+        /* search if stream is sendonly or recvonly */
+        int _remote_sendrecv = sdp_analyse_attribute (remote_sdp, remote_med);
+        int _local_sendrecv =  sdp_analyse_attribute (local_sdp, local_med);
+        _debug("            Remote SendRecv: %d\n", _remote_sendrecv);
+        _debug("            Local  SendRecv: %d\n", _local_sendrecv);
+        if (_local_sendrecv == _SENDRECV) {
+          if (_remote_sendrecv == _SENDONLY)      { _local_sendrecv = _RECVONLY; }
+          else if (_remote_sendrecv == _RECVONLY) { _local_sendrecv = _SENDONLY; }
+        }
+        _debug("            Final Local SendRecv: %d\n", _local_sendrecv);
+        sdp_message_free (local_sdp);
+      }
+      _debug("< Sending answer 183\n");
+      if (0 != eXosip_call_send_answer (event->tid, 183, answer)) {
+        _debug("SipCall::newIncomingCall: cannot send 183 progress?\n");
+      }
+    }
+  }
+  eXosip_unlock ();
+
+  sdp_message_free (remote_sdp);
+  return true;
+}
+
+/**
+  * newReinviteCall is called when the IP-Phone user receives a change in the call
+  * it's almost an newIncomingCall but we send a 200 OK
+  * See: 3.7.  Session with re-INVITE (IP Address Change)
+  * @param event eXosip Event
+  * @return true if ok
+  */
+bool 
+SIPCall::SIPCallReinvite(eXosip_event_t *event)
+{
+  if (event->cid < 1 && event->did < 1) {
+    _debug("SIP Failure: Invalid cid and did\n");
+    return false;
+  }
+
+  if (event->request == NULL) {
+    _debug("SIP Failure: No request into the event\n");
+    return false;
+  }
+
+  setCid(event->cid);
+  setDid(event->did);
+  setTid(event->tid);
+
+  setPeerInfoFromRequest(event);
+
+  sdp_message_t* remote_sdp = getRemoteSDPFromRequest(event);
+  if (remote_sdp == 0) {
+    return false;
+  }
+
+  sdp_media_t* remote_med = getRemoteMedia(event->tid, remote_sdp);
+  if (remote_med == 0) {
+    sdp_message_free (remote_sdp);
+    return false;
+  }
+
+  if (!setRemoteAudioFromSDP(remote_med, remote_sdp)) {
+    _debug("SIP Failure: unable to set IP address and port from SDP\n");
+    sdp_message_free (remote_sdp);
+    return false;
+  }
+
+  if (!setAudioCodecFromSDP(remote_med, event->tid)) {
+    sdp_message_free (remote_sdp);
+    return false;
+  }
+
+  osip_message_t *answer = 0;
+  eXosip_lock();
+  _debug("< Building Answer 200\n");
+  if (0 == eXosip_call_build_answer (event->tid, 200, &answer)) {
+    if ( 0 != sdp_complete_message(remote_sdp, answer)) {
+      osip_message_free(answer);
+      // Send 415 Unsupported media type
+      eXosip_call_send_answer (event->tid, 415, NULL);
+      _debug("< Sending Answer 415\n");
+    } else {
+
+      sdp_message_t *local_sdp = eXosip_get_sdp_info(answer);
+      sdp_media_t *local_med = NULL;
+      if (local_sdp != NULL) {
+         local_med = eXosip_get_audio_media(local_sdp);
+      }
+      if (local_sdp != NULL && local_med != NULL) {
+        /* search if stream is sendonly or recvonly */
+        int _remote_sendrecv = sdp_analyse_attribute (remote_sdp, remote_med);
+        int _local_sendrecv =  sdp_analyse_attribute (local_sdp, local_med);
+        _debug("            Remote SendRecv: %d\n", _remote_sendrecv);
+        _debug("            Local  SendRecv: %d\n", _local_sendrecv);
+        if (_local_sendrecv == _SENDRECV) {
+          if (_remote_sendrecv == _SENDONLY)      { _local_sendrecv = _RECVONLY; }
+          else if (_remote_sendrecv == _RECVONLY) { _local_sendrecv = _SENDONLY; }
+        }
+        _debug("            Final Local SendRecv: %d\n", _local_sendrecv);
+        sdp_message_free (local_sdp);
+      }
+      _debug("< Sending answer 200\n");
+      if (0 != eXosip_call_send_answer (event->tid, 200, answer)) {
+        _debug("SipCall::newIncomingCall: cannot send 200 OK?\n");
+      }
+    }
+  }
+  eXosip_unlock ();
+  sdp_message_free (remote_sdp);
+  return true;
+}
+
+  /**
+   * Peer answered to a call (on hold or not)
+   * @param event eXosip Event
+   * @return true if ok
+   */
+bool 
+SIPCall::SIPCallAnswered(eXosip_event_t *event)
+{
+  if (event->cid < 1 && event->did < 1) {
+    _debug("SIP Failure: Invalid cid and did\n");
+    return false;
+  }
+
+  if (event->request == NULL) {
+    _debug("SIP Failure: No request into the event\n");
+    return false;
+  }
+
+  setCid(event->cid);
+  setDid(event->did);
+
+  //setPeerInfoFromResponse()
+
+  eXosip_lock ();
+  {
+    osip_message_t *ack = NULL;
+    int i;
+    i = eXosip_call_build_ack (event->did, &ack);
+    if (i != 0) {
+      _debug("SipCall::answeredCall: Cannot build ACK for call!\n");
+    } else {
+      sdp_message_t *local_sdp = NULL;
+      sdp_message_t *remote_sdp = NULL;
+
+      if (event->request != NULL && event->response != NULL) {
+        local_sdp = eXosip_get_sdp_info (event->request);
+        remote_sdp = eXosip_get_sdp_info (event->response);
+      }
+      if (local_sdp == NULL && remote_sdp != NULL) {
+        /* sdp in ACK */
+        i = sdp_complete_message (remote_sdp, ack);
+        if (i != 0) {
+            _debug("SipCall::answeredCall: Cannot complete ACK with sdp body?!\n");
+        }
+      }
+      sdp_message_free (local_sdp);
+      sdp_message_free (remote_sdp);
+
+      _debug("< Send ACK\n");
+      eXosip_call_send_ack (event->did, ack);
+    }
+  }
+  eXosip_unlock ();
+  return true;  
+}
+  /**
+   * We retreive final SDP info if they changed
+   * @param event eXosip Event
+   * @return true if ok (change / no change) or false on error
+   */
+bool 
+SIPCall::SIPCallAnsweredWithoutHold(eXosip_event_t *event)
+{
+  if (event->response == NULL || event->request  == NULL) { return false; }
+  
+  eXosip_lock();
+  sdp_message_t *remote_sdp = eXosip_get_sdp_info (event->response);
+  eXosip_unlock();
+  if (remote_sdp == NULL) {
+    _debug("SIP Failure: no remote sdp\n");
+    sdp_message_free(remote_sdp);
+    return false;
+  }
+
+  sdp_media_t *remote_med = getRemoteMedia(event->tid, remote_sdp);
+  if (remote_med==NULL) {
+    sdp_message_free(remote_sdp);
+    return false;
+  }
+  if ( ! setRemoteAudioFromSDP(remote_med, remote_sdp) ) {
+    sdp_message_free(remote_sdp);
+    return false;
+  }
+
+  char *tmp = (char *) osip_list_get (remote_med->m_payloads, 0);
+
+  setAudioCodec(0);
+  if (tmp != NULL) {
+    int payload = atoi (tmp);
+    _debug("            Remote Payload: %d\n", payload);
+    setAudioCodec(_codecMap.getCodec((CodecType)payload)); // codec builder for the mic
+  }
+
+/*
+    // search if stream is sendonly or recvonly
+    _remote_sendrecv = sdp_analyse_attribute (remote_sdp, remote_med);
+    _local_sendrecv = sdp_analyse_attribute (local_sdp, local_med);
+    if (_local_sendrecv == _SENDRECV) {
+      if (_remote_sendrecv == _SENDONLY)
+          _local_sendrecv = _RECVONLY;
+      else if (_remote_sendrecv == _RECVONLY)
+          _local_sendrecv = _SENDONLY;
+    }
+  _debug("            Remote Sendrecv: %d\n", _remote_sendrecv);
+  _debug("            Local Sendrecv: %d\n", _local_sendrecv);
+*/
+  sdp_message_free (remote_sdp);
+  return true;
+}
+
+const std::string& 
+SIPCall::getLocalIp()
+{
+  ost::MutexLock m(_callMutex);  
+  return _localIPAddress;
+}
+
+unsigned int 
+SIPCall::getLocalAudioPort()
+{
+  ost::MutexLock m(_callMutex);  
+  return _localAudioPort;
+}
+
+unsigned int 
+SIPCall::getRemoteAudioPort()
+{
+  ost::MutexLock m(_callMutex);  
+  return _remoteAudioPort;
+}
+
+const std::string& 
+SIPCall::getRemoteIp()
+{
+  ost::MutexLock m(_callMutex);  
+  return _remoteIPAddress;
+}
+
+AudioCodec* 
+SIPCall::getAudioCodec()
+{
+  ost::MutexLock m(_callMutex);  
+  return _audioCodec;  
+}
+
+void 
+SIPCall::setAudioStart(bool start)
+{
+  ost::MutexLock m(_callMutex);  
+  _audioStarted = start;  
+}
+
+bool 
+SIPCall::isAudioStarted()
+{
+  ost::MutexLock m(_callMutex);  
+  return _audioStarted;
+}
+
+  //TODO: humm?
+int 
+SIPCall::sdp_complete_message(sdp_message_t * remote_sdp, osip_message_t * msg)
+{
+  // Format port to a char*
+  if (remote_sdp == NULL) {
+    _debug("SipCall::sdp_complete_message: No remote SDP body found for call\n");
+    return -1;
+  }
+  if (msg == NULL) {
+    _debug("SipCall::sdp_complete_message: No message to complete\n");
+    return -1;
+  }
+
+  std::ostringstream media;
+
+  // for each medias
+  int iMedia = 0;
+  char *tmp = NULL;
+  while (!osip_list_eol(remote_sdp->m_medias, iMedia)) {
+    sdp_media_t *remote_med = (sdp_media_t *)osip_list_get(remote_sdp->m_medias, iMedia);
+    if (remote_med == 0) { continue; }
+
+    if (0 != osip_strcasecmp (remote_med->m_media, "audio")) {
+      // if this is not an "audio" media, we set it to 0
+      media << "m=" << remote_med->m_media << " 0 " << remote_med->m_proto << " \r\n";
+    } else {
+      std::ostringstream listCodec;
+      std::ostringstream listRtpMap;
+
+      // search for compatible codec: foreach payload
+      int iPayload = 0;
+      while (!osip_list_eol(remote_med->m_payloads, iPayload)) {
+        tmp = (char *)osip_list_get(remote_med->m_payloads, iPayload);
+        if (tmp!=NULL) {
+          int payload = atoi(tmp);
+          AudioCodec* audiocodec = _codecMap.getCodec((CodecType)payload);
+          if (audiocodec!=0 && audiocodec->isActive()) {
+            listCodec << payload << " ";
+            listRtpMap << "a=rtpmap: " << payload << " " << audiocodec->getCodecName() << "/" << audiocodec->getClockRate();
+            if ( audiocodec->getChannel() != 1) {
+              listRtpMap << "/" << audiocodec->getChannel();
+            }
+            listRtpMap << "\r\n";
+          }
+        }
+        iPayload++;
+      }
+      if (listCodec.str().empty()) {
+        media << "m=" << remote_med->m_media << " 0 " << remote_med->m_proto << " \r\n";
+      } else {
+        // we add the media line + a=rtpmap list
+        media << "m=" << remote_med->m_media << " " << getLocalExternAudioPort() << " RTP/AVP " << listCodec.str() << "\r\n";
+        media << listRtpMap.str();
+      }
+    }
+    iMedia++;
+  }
+  char buf[4096];
+  snprintf (buf, 4096,
+    "v=0\r\n"
+    "o=user 0 0 IN IP4 %s\r\n"
+    "s=session\r\n"
+    "c=IN IP4 %s\r\n"
+    "t=0 0\r\n"
+    "%s\n", getLocalIp().c_str(), getLocalIp().c_str(), media.str().c_str());
+
+  osip_message_set_body (msg, buf, strlen (buf));
+  osip_message_set_content_type (msg, "application/sdp");
+  _debug("          sdp: %s", buf);
+  return 0;
+}
+
+
+  // TODO: hum???
+int 
+SIPCall::sdp_analyse_attribute (sdp_message_t * sdp, sdp_media_t * med)
+{
+  int pos;
+  int pos_media;
+
+  /* test media attributes */
+  pos = 0;
+  while (!osip_list_eol (med->a_attributes, pos)) {
+      sdp_attribute_t *at;
+
+      at = (sdp_attribute_t *) osip_list_get (med->a_attributes, pos);
+      if (at->a_att_field != NULL && 
+      0 == strcmp (at->a_att_field, "sendonly")) {
+      return _SENDONLY;
+      } else if (at->a_att_field != NULL &&
+                0 == strcmp (at->a_att_field, "recvonly")) {
+          return _RECVONLY;
+      } else if (at->a_att_field != NULL &&
+                0 == strcmp (at->a_att_field, "sendrecv")) {
+          return _SENDRECV;
+      }
+      pos++;
+  }
+
+  /* test global attributes */
+  pos_media = -1;
+  pos = 0;
+  while (!osip_list_eol (sdp->a_attributes, pos)) {
+      sdp_attribute_t *at;
+
+      at = (sdp_attribute_t *) osip_list_get (sdp->a_attributes, pos);
+      if (at->a_att_field != NULL && 
+      0 == strcmp (at->a_att_field, "sendonly")) {
+          return _SENDONLY;
+      } else if (at->a_att_field != NULL &&
+                0 == strcmp (at->a_att_field, "recvonly")) {
+          return _RECVONLY;
+      } else if (at->a_att_field != NULL &&
+                0 == strcmp (at->a_att_field, "sendrecv")) {
+          return _SENDRECV;
+      }
+      pos++;
+  }
+
+  return _SENDRECV;
+}
+
+bool 
+SIPCall::setPeerInfoFromRequest(eXosip_event_t *event)
+{
+  // event->request should not be NULL!
+  char remote_uri[256] = "";
+  std::string name("");
+  std::string number("");
+
+  char *tmp = NULL;
+  osip_from_to_str(event->request->from, &tmp);
+  if (tmp != NULL) {
+    snprintf (remote_uri, 255, "%s", tmp);
+    remote_uri[255] = '\0';
+    osip_free (tmp);
+
+    // Get the name/number
+    osip_from_t *from;
+    osip_from_init(&from);
+    osip_from_parse(from, remote_uri);
+    char *tmpname = osip_from_get_displayname(from);
+    if ( tmpname != NULL ) {
+      name = tmpname;
+    }
+    osip_uri_t* url = osip_from_get_url(from); 
+    if ( url != NULL && url->username != NULL) {
+      number = url->username;
+    }
+    osip_from_free(from);
+  }
+
+  _debug("            Name: %s\n", name.c_str());
+  _debug("            Number: %s\n", number.c_str());
+  _debug("            Remote URI: %s\n", remote_uri);
+
+  setPeerName(name);
+  setPeerNumber(number);  
+  return true;
+}
+
+sdp_message_t* 
+SIPCall::getRemoteSDPFromRequest(eXosip_event_t *event)
+{
+  // event->request should not be null!
+  /* negotiate payloads */
+  sdp_message_t *remote_sdp = NULL;
+  if (event->request != NULL) {
+    eXosip_lock();
+    remote_sdp = eXosip_get_sdp_info (event->request);
+    eXosip_unlock();
+  }
+  if (remote_sdp == NULL) {
+    _debug("SIP Failure: No SDP into the request\n");
+    _debug("< Sending 400 Bad Request (no SDP)\n");
+    eXosip_lock();
+    eXosip_call_send_answer (event->tid, 400, NULL);
+    eXosip_unlock();
+    return 0;
+  }
+  return remote_sdp;
+}
+
+sdp_media_t* 
+SIPCall::getRemoteMedia(int tid, sdp_message_t* remote_sdp)
+{
+  // Remote Media Port
+  eXosip_lock();
+  sdp_media_t *remote_med = eXosip_get_audio_media(remote_sdp);
+  eXosip_unlock();
+
+  if (remote_med == NULL || remote_med->m_port == NULL) {
+    // no audio media proposed
+    _debug("SIP Failure: unsupported media\n");
+    _debug("< Sending 415 Unsupported media type\n");
+    eXosip_lock();
+    eXosip_call_send_answer (tid, 415, NULL);
+    eXosip_unlock();
+    sdp_message_free (remote_sdp);
+    return 0;
+  }
+  return remote_med;
+}
+
+bool 
+SIPCall::setRemoteAudioFromSDP(sdp_media_t* remote_med, sdp_message_t* remote_sdp)
+{
+  // Remote Media IP
+  eXosip_lock();
+  sdp_connection_t *conn = eXosip_get_audio_connection(remote_sdp);
+  eXosip_unlock();
+  if (conn != NULL && conn->c_addr != NULL) {
+    char _remote_sdp_audio_ip[50] = "";
+    snprintf (_remote_sdp_audio_ip, 49, "%s", conn->c_addr);
+    _remote_sdp_audio_ip[49] = '\0';
+    _debug("            Remote Audio IP: %s\n", _remote_sdp_audio_ip);
+    setRemoteIP(_remote_sdp_audio_ip);
+    if (_remote_sdp_audio_ip[0] == '\0') {
+      setRemoteAudioPort(0);
+      return false;
+    }
+  }
+
+  // Remote port
+  int _remote_sdp_audio_port = atoi(remote_med->m_port);
+  _debug("            Remote Audio Port: %d\n", _remote_sdp_audio_port);
+  setRemoteAudioPort(_remote_sdp_audio_port);
+
+  if (_remote_sdp_audio_port == 0) {
+    return false;
+  }
+  return true;
+}
+
+bool 
+SIPCall::setAudioCodecFromSDP(sdp_media_t* remote_med, int tid)
+{
+  // Remote Payload
+  char *tmp = NULL;
+  int pos = 0;
+  while (!osip_list_eol (remote_med->m_payloads, pos)) {
+    tmp = (char *) osip_list_get (remote_med->m_payloads, pos);
+    if (tmp != NULL ) {
+      int payload = atoi(tmp);
+      // stop if we find a correct codec
+      if (0 != _codecMap.getCodec((CodecType)payload)){
+          break;
+      }
+    }
+    tmp = NULL;
+    pos++;
+  }
+
+  setAudioCodec(0);
+  if (tmp != NULL) {
+    int payload = atoi (tmp);
+    _debug("            Payload: %d\n", payload);
+    setAudioCodec(_codecMap.getCodec((CodecType)payload)); // codec builder for the mic
+  }
+  if (getAudioCodec() == 0) {
+    _debug("SIPCall Failure: Unable to set codec\n");
+    _debug("< Sending 415 Unsupported media type\n");
+    eXosip_lock();
+    eXosip_call_send_answer(tid, 415, NULL);
+    eXosip_unlock();
+    return false;
+  }
+  return true;
+}
-- 
GitLab