bool AmSession::isAudioSet() { lockAudio(); bool set = input || output; unlockAudio(); return set; }
void AmSession::setInOut(AmAudio* in,AmAudio* out) { lockAudio(); input = in; output = out; unlockAudio(); }
void AmSession::setOnHold(bool hold) { lockAudio(); bool old_hold = RTPStream()->getOnHold(); RTPStream()->setOnHold(hold); if (hold != old_hold) sendReinvite(); unlockAudio(); }
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; }
int AmSession::acceptAudio(const string& body, const string& hdrs, string* sdp_reply) { try { try { // handle codec and send reply string str_msg_flags = getHeader(hdrs,"P-MsgFlags"); unsigned int msg_flags = 0; if(reverse_hex2int(str_msg_flags,msg_flags)){ ERROR("while parsing 'P-MsgFlags' header\n"); msg_flags = 0; } negotiate( body, msg_flags & FL_FORCE_ACTIVE, sdp_reply); // enable RTP stream lockAudio(); rtp_str.init(&payload); unlockAudio(); DBG("Sending Rtp data to %s/%i\n", rtp_str.getRHost().c_str(),rtp_str.getRPort()); return 0; } catch(const AmSession::Exception& e){ throw e; } catch(const string& str){ ERROR("%s\n",str.c_str()); throw AmSession::Exception(500,str); } catch(...){ throw AmSession::Exception(500,"unexpected exception."); } } catch(const AmSession::Exception& e){ ERROR("%i %s\n",e.code,e.reason.c_str()); throw; // if(dlg.reply(req,e.code,e.reason, "")){ // dlg.bye(); // } // setStopped(); } return -1; }
void AmSession::clearAudio() { lockAudio(); if(input){ input->close(); input = 0; } if(output){ output->close(); output = 0; } unlockAudio(); DBG("Audio cleared !!!\n"); postEvent(new AmAudioEvent(AmAudioEvent::cleared)); }
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; }
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; }
void AmSession::setOutput(AmAudio* out) { lockAudio(); output = out; unlockAudio(); }
void AmSession::setInput(AmAudio* in) { lockAudio(); input = in; unlockAudio(); }
void AmSession::negotiate(const string& sdp_body, bool force_symmetric_rtp, string* sdp_reply) { string r_host = ""; int r_port = 0; sdp.setBody(sdp_body.c_str()); if(sdp.parse()) throw AmSession::Exception(400,"session description parsing failed"); if(sdp.media.empty()) throw AmSession::Exception(400,"no media line found in SDP message"); SdpPayload* tmp_pl = sdp.getCompatiblePayload(MT_AUDIO,r_host,r_port); if(!tmp_pl) throw AmSession::Exception(606,"could not find compatible payload"); if(payload.int_pt == -1){ payload = *tmp_pl; DBG("new payload: %i\n",payload.int_pt); } else if(payload.int_pt != tmp_pl->int_pt){ DBG("old payload: %i; new payload: %i\n",payload.int_pt,tmp_pl->int_pt); throw AmSession::Exception(400,"do not accept payload changes"); } const SdpPayload *telephone_event_payload = sdp.telephoneEventPayload(); if(telephone_event_payload) { DBG("remote party supports telephone events (pt=%i)\n", telephone_event_payload->payload_type); lockAudio(); rtp_str.setTelephoneEventPT(telephone_event_payload); unlockAudio(); } else { DBG("remote party doesn't support telephone events\n"); } bool passive_mode = false; if( sdp.remote_active || force_symmetric_rtp) { DBG("The other UA is NATed: switched to passive mode.\n"); DBG("remote_active = %i; force_symmetric_rtp = %i\n", sdp.remote_active,force_symmetric_rtp); passive_mode = true; } lockAudio(); rtp_str.setLocalIP(AmConfig::LocalIP); rtp_str.setPassiveMode(passive_mode); rtp_str.setRAddr(r_host, r_port); unlockAudio(); if(sdp_reply) sdp.genResponse(AmConfig::LocalIP,rtp_str.getLocalPort(),*sdp_reply); }