Example #1
0
/** Hook called when an SDP offer is required */
bool AmSession::getSdpOffer(AmSdp& offer)
{
  DBG("AmSession::getSdpOffer(...) ...\n");

  offer.version = 0;
  offer.origin.user = "******";
  //offer.origin.sessId = 1;
  //offer.origin.sessV = 1;
  offer.sessionName = "sems";
  offer.conn.network = NT_IN;
  offer.conn.addrType = AT_V4;
  offer.conn.address = advertisedIP();

  // TODO: support mutiple media types (needs multiples RTP streams)
  // TODO: support update instead of clearing everything

  if(RTPStream()->getSdpMediaIndex() < 0)
    offer.media.clear();

  unsigned int media_idx = 0;
  if(!offer.media.size()) {
    offer.media.push_back(SdpMedia());
    offer.media.back().type=MT_AUDIO;
  }
  else {
    media_idx = RTPStream()->getSdpMediaIndex();
  }

  RTPStream()->setLocalIP(localMediaIP());
  RTPStream()->getSdpOffer(media_idx,offer.media.back());
  
  return true;
}
Example #2
0
void AmSession::setOnHold(bool hold)
{
  lockAudio();
  bool old_hold = RTPStream()->getOnHold();
  RTPStream()->setOnHold(hold);
  if (hold != old_hold) 
    sendReinvite();
  unlockAudio();
}
Example #3
0
string AmSession::sid4dbg()
{
  string dbg;
  dbg = dlg->getCallid() + "/" + dlg->getLocalTag() + "/" 
    + dlg->getRemoteTag() + "/" 
    + int2str(RTPStream()->getLocalPort()) + "/" 
    + RTPStream()->getRHost() + ":" + int2str(RTPStream()->getRPort());
  return dbg;
}
Example #4
0
CallBackDialog::CallBackDialog(AmPromptCollection& prompts,
			       UACAuthCred* cred)
  : play_list(this),  prompts(prompts), cred(cred),
    state(CBNone)
{
  // set configured playout type
  RTPStream()->setPlayoutType(CallBackFactory::m_PlayoutType);
}
Example #5
0
CallBackCalleeDialog::CallBackCalleeDialog(const string& other_tag, 
					   AmSessionAudioConnector* connector,
					   UACAuthCred* cred) 
  : AmB2ABCalleeSession(other_tag, connector), cred(cred)
{
  // set configured playout type
  RTPStream()->setPlayoutType(CallBackFactory::m_PlayoutType);
  setDtmfDetectionEnabled(false);
}
Example #6
0
int AmSession::onSdpCompleted(const AmSdp& local_sdp, const AmSdp& remote_sdp)
{
  DBG("AmSession::onSdpCompleted(...) ...\n");

  if(local_sdp.media.empty() || remote_sdp.media.empty()) {

    ERROR("Invalid SDP");

    string debug_str;
    local_sdp.print(debug_str);
    ERROR("Local SDP:\n%s",
	  debug_str.empty() ? "<empty>"
	  : debug_str.c_str());
    
    remote_sdp.print(debug_str);
    ERROR("Remote SDP:\n%s",
	  debug_str.empty() ? "<empty>"
	  : debug_str.c_str());

    return -1;
  }

  bool set_on_hold = false;
  if (!remote_sdp.media.empty()) {
    vector<SdpAttribute>::const_iterator pos =
      std::find(remote_sdp.media[0].attributes.begin(), remote_sdp.media[0].attributes.end(), SdpAttribute("sendonly"));
    set_on_hold = pos != remote_sdp.media[0].attributes.end();
  }

  lockAudio();

  // TODO: 
  //   - get the right media ID
  //   - check if the stream coresponding to the media ID 
  //     should be created or updated   
  //
  int ret = 0;

  try {
    ret = RTPStream()->init(local_sdp, remote_sdp, AmConfig::ForceSymmetricRtp);
  } catch (const string& s) {
    ERROR("Error while initializing RTP stream: '%s'\n", s.c_str());
    ret = -1;
  } catch (...) {
    ERROR("Error while initializing RTP stream (unknown exception in AmRTPStream::init)\n");
    ret = -1;
  }
  unlockAudio();

  if (!isProcessingMedia()) {
    setInbandDetector(AmConfig::DefaultDTMFDetector);
  }

  return ret;
}
WebConferenceDialog::WebConferenceDialog(AmPromptCollection& prompts,
					 WebConferenceFactory* my_f,
					 UACAuthCred* cred)
  : play_list(this), separator(this, 0), prompts(prompts), state(None),
    factory(my_f), cred(cred), muted(false), 
    connect_ts(-1), disconnect_ts(-1) 
{
  is_dialout = (cred != NULL);
  accept_early_session = is_dialout;
  // set configured playout type
  RTPStream()->setPlayoutType(WebConferenceFactory::m_PlayoutType);
}
WebConferenceDialog::WebConferenceDialog(AmPromptCollection& prompts,
					 WebConferenceFactory* my_f,
					 const string& room)
  : play_list(this), separator(this, 0), prompts(prompts), state(None),
    factory(my_f), muted(false), 
    connect_ts(-1), disconnect_ts(-1)
{
  conf_id = room;
  DBG("set conf_id to %s\n", conf_id.c_str());
  is_dialout = false;
  // set configured playout type
  RTPStream()->setPlayoutType(WebConferenceFactory::m_PlayoutType);
}
/*  循环产生一个能唯一标识该RTPSession的RTPStream数组中新的RTPStream的随机数(作为SSRC),搭建一个新的RTPStream,放入RTPStream的数组 */
QTSS_Error RTPSession::AddStream(RTSPRequestInterface* request, RTPStream** outStream, QTSS_AddStreamFlags inFlags)
{
    Assert(outStream != NULL);

    // Create a new SSRC for this stream. This should just be a random number unique
    // to all the streams in the session
	/* 循环产生一个能唯一标识该RTPSession的RTPStream数组中新的RTPStream的随机数,作为SSRC(它和该数组中现存的每个RTPStream的SSRC都不同) */
    UInt32 theSSRC = 0;
    while (theSSRC == 0)
    {
		/* 产生随机数,它在该RTPSession的RTPStream数组中唯一标识一个RTPSream */
        theSSRC = (SInt32)::rand();

        RTPStream** theStream = NULL;
        UInt32 theLen = 0;
    
		/* 遍历RTPSession中的每个RTPStream,若它的SSRC恰和theSSRC相同,就将theSSRC置0,使得该循环继续 */
        for (int x = 0; this->GetValuePtr(qtssCliSesStreamObjects, x, (void**)&theStream, &theLen) == QTSS_NoErr; x++)
        {
            Assert(theStream != NULL);
            Assert(theLen == sizeof(RTPStream*));
            
            if (*theStream != NULL)
                if ((*theStream)->GetSSRC() == theSSRC)
                    theSSRC = 0;
        }
    }

	/***************** 新建一个RTPStream对象,它有唯一标识它的SSRC(随机数) *************/
    *outStream = NEW RTPStream(theSSRC, this);
	/***************** 新建一个RTPStream对象 *************/
    
	/* 以指定加入方式搭建该RTSP Request的RTPStream */
    QTSS_Error theErr = (*outStream)->Setup(request, inFlags);
	/* 假如搭建不成功,就删去新建RTPStream对象 */
    if (theErr != QTSS_NoErr)
        // If we couldn't setup the stream, make sure not to leak memory!
        delete *outStream;
	/* 假如搭建成功,将其放入RTPStream Array中,注意下面qtssCliSesStreamObjects是个多值索引的属性 */
    else
    {
        // If the stream init succeeded, then put it into the array of setup streams
        theErr = this->SetValue(qtssCliSesStreamObjects, this->GetNumValues(qtssCliSesStreamObjects),
                                                    outStream, sizeof(RTPStream*), QTSSDictionary::kDontObeyReadOnly);
        Assert(theErr == QTSS_NoErr);
        fHasAnRTPStream = true;/* 现在有一个RTPStream */
    }

    return theErr;
}
Example #10
0
int AmSession::writeStreams(unsigned long long ts, unsigned char *buffer) 
{ 
  int res = 0;
  lockAudio();

  AmRtpAudio *stream = RTPStream();
  if (stream->sendIntReached()) { // FIXME: shouldn't depend on checkInterval call before!
    unsigned int f_size = stream->getFrameSize();
    int got = 0;
    if (output) got = output->get(ts, buffer, stream->getSampleRate(), f_size);
    if (got < 0) res = -1;
    if (got > 0) res = stream->put(ts, buffer, stream->getSampleRate(), got);
  }
  
  unlockAudio();
  return res;

}
Example #11
0
QTSS_Error RTPSession::AddStream(RTSPRequestInterface* request, RTPStream** outStream,
                                        QTSS_AddStreamFlags inFlags)
{
    Assert(outStream != NULL);

    // Create a new SSRC for this stream. This should just be a random number unique
    // to all the streams in the session
    UInt32 theSSRC = 0;
    while (theSSRC == 0)
    {
        theSSRC = (SInt32)::rand();

        RTPStream** theStream = NULL;
        UInt32 theLen = 0;
    
        for (int x = 0; this->GetValuePtr(qtssCliSesStreamObjects, x, (void**)&theStream, &theLen) == QTSS_NoErr; x++)
        {
            Assert(theStream != NULL);
            Assert(theLen == sizeof(RTPStream*));
            
            if (*theStream != NULL)
                if ((*theStream)->GetSSRC() == theSSRC)
                    theSSRC = 0;
        }
    }

    *outStream = NEW RTPStream(theSSRC, this);
    
    QTSS_Error theErr = (*outStream)->Setup(request, inFlags);
    if (theErr != QTSS_NoErr)
        // If we couldn't setup the stream, make sure not to leak memory!
        delete *outStream;
    else
    {
        // If the stream init succeeded, then put it into the array of setup streams
        theErr = this->SetValue(qtssCliSesStreamObjects, this->GetNumValues(qtssCliSesStreamObjects),
                                                    outStream, sizeof(RTPStream*), QTSSDictionary::kDontObeyReadOnly);
        Assert(theErr == QTSS_NoErr);
        fHasAnRTPStream = true;
    }
    return theErr;
}
Example #12
0
int AmSession::readStreams(unsigned long long ts, unsigned char *buffer) 
{ 
  int res = 0;
  lockAudio();

  AmRtpAudio *stream = RTPStream();
  unsigned int f_size = stream->getFrameSize();
  if (stream->checkInterval(ts)) {
    int got = stream->get(ts, buffer, stream->getSampleRate(), f_size);
    if (got < 0) res = -1;
    if (got > 0) {
      if (isDtmfDetectionEnabled())
        putDtmfAudio(buffer, got, ts);

      if (input) res = input->put(ts, buffer, stream->getSampleRate(), got);
    }
  }
  
  unlockAudio();
  return res;
}
Example #13
0
int AmB2BSession::onSdpCompleted(const AmSdp& local_sdp, const AmSdp& remote_sdp)
{
  if (rtp_relay_mode != RTP_Direct) {
    if (!media_session) {
      // report missing media session (here we get for rtp_relay_mode == RTP_Relay)
      ERROR("BUG: media session is missing, can't update SDP\n");
    }
    else {
      media_session->updateStreams(a_leg, local_sdp, remote_sdp, this);
    }
  }

  if(hasRtpStream() && RTPStream()->getSdpMediaIndex() >= 0) {
    if(!sip_relay_only){
      return AmSession::onSdpCompleted(local_sdp,remote_sdp);
    }
    DBG("sip_relay_only = true: doing nothing!\n");
  }

  return 0;
}
Example #14
0
/** Hook called when an SDP answer is required */
bool AmSession::getSdpAnswer(const AmSdp& offer, AmSdp& answer)
{
  DBG("AmSession::getSdpAnswer(...) ...\n");

  answer.version = 0;
  answer.origin.user = "******";
  //answer.origin.sessId = 1;
  //answer.origin.sessV = 1;
  answer.sessionName = "sems";
  answer.conn.network = NT_IN;
  if (offer.conn.address.empty()) answer.conn.addrType = AT_V4; // or use first stream connection?
  else answer.conn.addrType = offer.conn.addrType;
  answer.conn.address = advertisedIP(answer.conn.addrType);
  answer.media.clear();
  
  bool audio_1st_stream = true;
  unsigned int media_index = 0;
  for(vector<SdpMedia>::const_iterator m_it = offer.media.begin();
      m_it != offer.media.end(); ++m_it) {

    answer.media.push_back(SdpMedia());
    SdpMedia& answer_media = answer.media.back();

    if( m_it->type == MT_AUDIO
	&& m_it->transport == TP_RTPAVP
        && audio_1st_stream 
        && (m_it->port != 0) ) {

      RTPStream()->setLocalIP(localMediaIP(answer.conn.addrType));
      RTPStream()->getSdpAnswer(media_index,*m_it,answer_media);
      if(answer_media.payloads.empty() ||
	 ((answer_media.payloads.size() == 1) &&
	  (answer_media.payloads[0].encoding_name == "telephone-event"))
	 ){
	// no compatible media found
	throw Exception(488,"no compatible payload");
      }
      audio_1st_stream = false;
    }
    else {
      
      answer_media.type = m_it->type;
      answer_media.port = 0;
      answer_media.nports = 0;
      answer_media.transport = m_it->transport;
      answer_media.send = false;
      answer_media.recv = false;
      answer_media.payloads.clear();
      if(!m_it->payloads.empty()) {
	SdpPayload dummy_pl = m_it->payloads.front();
	dummy_pl.encoding_name.clear();
	dummy_pl.sdp_format_parameters.clear();
	answer_media.payloads.push_back(dummy_pl);
      }
      answer_media.attributes.clear();
    }

    // sort payload type in the answer according to the priority given in the codec_order configuration key
    std::stable_sort(answer_media.payloads.begin(),answer_media.payloads.end(),codec_priority_cmp());

    media_index++;
  }

  return true;
}
Click2TransSession::Click2TransSession(Click2TransDialog* parentDialog) : 
  dialog(parentDialog),ringTone(new AmRingTone(0,2000,4000,440,480))
{
  RTPStream()->setPlayoutType(ADAPTIVE_PLAYOUT);
  setCallgroup(dialog->getID());
}
Example #16
0
void AmSession::sendDtmf(int event, unsigned int duration_ms) {
  RTPStream()->sendDtmf(event, duration_ms);
}
Example #17
0
void AmSession::setInbandDetector(Dtmf::InbandDetectorType t)
{ 
  m_dtmfDetector.setInbandDetector(t, RTPStream()->getSampleRate()); 
}
Example #18
0
int AmSession::getRPort()
{
  return RTPStream()->getRPort();
}
PinAuthConferenceDialog::PinAuthConferenceDialog(AmPromptCollection& prompts)
  : play_list(this), separator(this, 0), prompts(prompts), state(None)
{
  // set configured playout type
  RTPStream()->setPlayoutType(PinAuthConferenceFactory::m_PlayoutType);
}