示例#1
0
void AmZRTP::on_zrtp_protocol_event(zrtp_stream_t *stream, zrtp_protocol_event_t event) {
  DBG("on_zrtp_protocol_event(stream [%p])\n", stream);
  if (NULL==stream) {
    ERROR("event received without stream context.\n");
    return;
  }
  void* udata = zrtp_stream_get_userdata(stream);
  if (NULL == udata) {
    ERROR("ZRTP on_send_packet without session set context.\n");
    return;
  }
  AmSession* sess = reinterpret_cast<AmSession*>(udata);
  sess->postEvent(new AmZRTPProtocolEvent(event, stream));
}
void AmSessionContainer::startSessionUAS(AmSipRequest& req)
{
  as_mut.lock();
  try {
	
    AmSession* session = getSession(req.callid,req.from_tag);
    if( session ){
	    
      // it's a forked-and-merged INVITE
      // reply 482 Loop detected
      throw AmSession::Exception(482, "Loop detected");
    }
    else {
      // Call-ID and From-Tag are unknown: it's a new session
      AmSession* session;
      if((session = createSession(req)) != 0){

	// update session's local tag (ID) if not already set
	session->setLocalTag();
	const string& local_tag = session->getLocalTag();
	// by default each session is in its own callgroup
	session->setCallgroup(local_tag);

	if (AmConfig::LogSessions) {
	  INFO("Starting UAS session %s app %s\n",
	       session->getLocalTag().c_str(), req.cmd.c_str());
	}

	session->start();

	addSession_unsafe(req.callid,req.from_tag,local_tag,session);
	session->postEvent(new AmSipRequestEvent(req));
      }
    }
  } 
  catch(const AmSession::Exception& e){
    ERROR("%i %s\n",e.code,e.reason.c_str());
    AmSipDialog::reply_error(req,e.code,e.reason);
  }
  catch(const string& err){
    ERROR("startSession: %s\n",err.c_str());
    AmSipDialog::reply_error(req,500,err);
  }
  catch(...){
    ERROR("unexpected exception\n");
    AmSipDialog::reply_error(req,500,"unexpected exception");
  }
  as_mut.unlock();
}
示例#3
0
void zrtp_event_callback(zrtp_event_t event, zrtp_stream_ctx_t *stream_ctx)
{
  if (NULL==stream_ctx) {
    ERROR("event received without stream context.\n");
    return;
  }

  AmSession* sess = reinterpret_cast<AmSession*>(stream_ctx->stream_usr_data);
  if (NULL==sess) {
    ERROR("event received without session set up.\n");
    return;
  }

  sess->postEvent(new AmZRTPEvent(event, stream_ctx));
}
void AmSessionContainer::startSessionUAS(AmSipRequest& req)
{
  as_mut.lock();
  try {
	
    AmSession* session = getSession(req.callid,req.from_tag);
    if( session ){
	    
      // it's a forked-and-merged INVITE
      // reply 482 Loop detected
      throw AmSession::Exception(482, "Loop detected");
    }
    else {
      // Call-ID and From-Tag are unknown: it's a new session
      AmSession* session;
      if((session = createSession(req)) != 0){

	string local_tag = AmSession::getNewId();
	session->setLocalTag(local_tag);
	session->setCallgroup(local_tag);
	session->start();

	addSession_unsafe(req.callid,req.from_tag,local_tag,session);
	session->postEvent(new AmSipRequestEvent(req));
      }
      //else
      //throw AmSession::Exception(500,"internal error");
    }
  } 
  //     catch(const AmSession::SessionTimerException& e){
  //  	ERROR("%i %s\n",e.code,e.reason.c_str());
  // 	AmSipDialog::reply_error(req,e.code,e.reason,e.getErrorHeaders());
  //     }
  catch(const AmSession::Exception& e){
    ERROR("%i %s\n",e.code,e.reason.c_str());
    AmSipDialog::reply_error(req,e.code,e.reason);
  }
  catch(const string& err){
    ERROR("startSession: %s\n",err.c_str());
    AmSipDialog::reply_error(req,500,err);
  }
  catch(...){
    ERROR("unexpected exception\n");
    AmSipDialog::reply_error(req,500,"unexpected exception");
  }
  as_mut.unlock();
}
bool AmSessionContainer::postEvent(const string& callid, 
				   const string& remote_tag,
				   AmEvent* event)
{
  //     DBG("postEvent: callid = %s; remote_tag = %s\n",
  // 	callid.c_str(),remote_tag.c_str());

  as_mut.lock();
  AmSession* s = getSession(callid,remote_tag);
  as_mut.unlock();
    
  if(!s){
    delete event;
    return false;
  }
    
  s->postEvent(event);
  return true;
}
bool AmSessionContainer::postEvent(const string& local_tag,
				   AmEvent* event) 
{
  //     DBG("postEvent: local_tag = %s\n",local_tag.c_str());
  as_mut.lock();
  AmSession* s = getSession(local_tag);
  as_mut.unlock();

  if (s  != NULL) {
    s->postEvent(event);
    return true;
  }    
	
  // try session factories
  AmSessionFactory* sf = AmPlugIn::instance()->getFactory4App(local_tag);
  if (sf != NULL) {
    sf->postEvent(event);
    return true;
  }

  delete event;
  return false;
}
void AmMediaProcessorThread::processAudio(unsigned int ts)
{
    for(set<AmSession*>::iterator it = sessions.begin();
	it != sessions.end(); it++){

	AmSession* s = (*it);
	s->lockAudio();
	AmAudio* input = s->getInput();

	if(s->rtp_str.checkInterval(ts)){

	    //DBG("ts = %u\n",ts);
	    int ret = s->rtp_str.receive(ts);
	    if(ret < 0){
		switch(ret){

		    case RTP_DTMF:
		    case RTP_UNKNOWN_PL:
		    case RTP_PARSE_ERROR:
			break;

		    case RTP_TIMEOUT:
			    postRequest(new SchedRequest(AmMediaProcessor::RemoveSession,s));
			    s->postEvent(new AmRtpTimeoutEvent());
			    break;

		    case RTP_BUFFER_SIZE:
		    default:
			ERROR("AmRtpAudio::receive() returned %i\n",ret);
			postRequest(new SchedRequest(AmMediaProcessor::ClearSession,s));
			break;
		}
	    }
	    else {
		unsigned int f_size = s->rtp_str.getFrameSize();
		int size = s->rtp_str.get(ts,buffer,f_size);
		if (input) {
		    
		    int ret = input->put(ts,buffer,size);
		    if(ret < 0){
			DBG("input->put() returned: %i\n",ret);
			postRequest(new SchedRequest(AmMediaProcessor::ClearSession,s));
		    }
		}
                if (s->isDtmfDetectionEnabled())
                    s->putDtmfAudio(buffer, size, ts);
            }
	}
	s->unlockAudio();
    }

    for(set<AmSession*>::iterator it = sessions.begin();
	it != sessions.end(); it++){

	AmSession* s = (*it);
	s->lockAudio();
	AmAudio* output = s->getOutput();
	    
	if(output && s->rtp_str.sendIntReached()){
		
	    int size = output->get(ts,buffer,s->rtp_str.getFrameSize());
	    if(size <= 0){
		DBG("output->get() returned: %i\n",size);
		postRequest(new SchedRequest(AmMediaProcessor::ClearSession,s)); //removeSession(s);
	    }
	    else if(!s->rtp_str.mute){
		
		if(s->rtp_str.put(ts,buffer,size)<0)
		  postRequest(new SchedRequest(AmMediaProcessor::ClearSession,s));
		//		    removeSession(s);
	    }
	}
	s->unlockAudio();
    }	
}
void AmMediaProcessorThread::processAudio(unsigned int ts)
{
  // receiving
  for(set<AmSession*>::iterator it = sessions.begin();
      it != sessions.end(); it++){

    AmSession* s = (*it);
    // todo: get frame size/checkInterval from local audio if local in+out (?)
    unsigned int frame_length = s->rtp_str.getFrameLength(); // ms

    // complete frame time reached? 
    if (s->rtp_str.checkInterval(ts)) {
      s->lockAudio();

      int rcvd_audio_len = -1;

      // get/receive audio
      if (!s->getAudioLocal(AM_AUDIO_IN)) {
	// input is not local - receive from rtp stream
	if (s->rtp_str.receiving || s->rtp_str.getPassiveMode()) {
	  int ret = s->rtp_str.receive(ts);
	  if(ret < 0){
	    switch(ret){
	      
	    case RTP_DTMF:
	    case RTP_UNKNOWN_PL:
	    case RTP_PARSE_ERROR:
	      break;
	      
	    case RTP_TIMEOUT:
	      postRequest(new SchedRequest(AmMediaProcessor::RemoveSession,s));
	      s->postEvent(new AmRtpTimeoutEvent());
	      break;
	      
	    case RTP_BUFFER_SIZE:
	    default:
	      ERROR("AmRtpAudio::receive() returned %i\n",ret);
	      postRequest(new SchedRequest(AmMediaProcessor::ClearSession,s));
	      break;
	    }
	  } else {
	    rcvd_audio_len = s->rtp_str.get(ts,buffer,frame_length);
	    
	    if (s->isDtmfDetectionEnabled() && rcvd_audio_len > 0)
	      s->putDtmfAudio(buffer, rcvd_audio_len, ts);
	  }
	}
      } else {
	// input is local - get audio from local_in
	AmAudio* local_input = s->getLocalInput(); 
	if (local_input) {
	  rcvd_audio_len = local_input->get(ts,buffer,frame_length);
	}
      }

      // process received audio
      if (rcvd_audio_len >= 0) {
	AmAudio* input = s->getInput();
	if (input) {
	  int ret = input->put(ts,buffer,rcvd_audio_len);
	  if(ret < 0){
	    DBG("input->put() returned: %i\n",ret);
	    postRequest(new SchedRequest(AmMediaProcessor::ClearSession,s));
	  }
	}
      }

      s->unlockAudio();
    }
  }

  // sending
  for(set<AmSession*>::iterator it = sessions.begin();
      it != sessions.end(); it++){

    AmSession* s = (*it);
    s->lockAudio();
    AmAudio* output = s->getOutput();
	    
    if(output && s->rtp_str.sendIntReached()){
      unsigned int frame_length = s->rtp_str.getFrameLength();
      int size = output->get(ts,buffer,frame_length);

      if(size <= 0){
	DBG("output->get() returned: %i\n",size);
	postRequest(new SchedRequest(AmMediaProcessor::ClearSession,s)); 
      }
      else {
	if (!s->getAudioLocal(AM_AUDIO_OUT)) {
	  // audio should go to RTP
	  if(!s->rtp_str.mute){	     
	    if(s->rtp_str.put(ts,buffer,size)<0)
	      postRequest(new SchedRequest(AmMediaProcessor::ClearSession,s));
	  }
	} else {
	  // output is local - audio should go in local_out
	  AmAudio* local_output = s->getLocalOutput(); 
	  if (local_output) {
	    if (local_output->put(ts,buffer,size)) {
	      postRequest(new SchedRequest(AmMediaProcessor::ClearSession,s));
	    }
	  }
	}
      }
    }
    s->unlockAudio();
  }	
}