void AudioStream::stateChanged(pa_stream* s) { UNUSED char str[PA_SAMPLE_SPEC_SNPRINT_MAX]; switch (pa_stream_get_state(s)) { case PA_STREAM_CREATING: RING_DBG("Stream is creating..."); break; case PA_STREAM_TERMINATED: RING_DBG("Stream is terminating..."); break; case PA_STREAM_READY: RING_DBG("Stream successfully created, connected to %s", pa_stream_get_device_name(s)); //RING_DBG("maxlength %u", pa_stream_get_buffer_attr(s)->maxlength); //RING_DBG("tlength %u", pa_stream_get_buffer_attr(s)->tlength); //RING_DBG("prebuf %u", pa_stream_get_buffer_attr(s)->prebuf); //RING_DBG("minreq %u", pa_stream_get_buffer_attr(s)->minreq); //RING_DBG("fragsize %u", pa_stream_get_buffer_attr(s)->fragsize); //RING_DBG("samplespec %s", pa_sample_spec_snprint(str, sizeof(str), pa_stream_get_sample_spec(s))); break; case PA_STREAM_UNCONNECTED: RING_DBG("Stream unconnected"); break; case PA_STREAM_FAILED: default: RING_ERR("Stream failure: %s" , pa_strerror(pa_context_errno(pa_stream_get_context(s)))); break; } }
SipIceTransport::~SipIceTransport() { RING_DBG("~SipIceTransport@%p", this); Manager::instance().unregisterEventHandler((uintptr_t)this); pj_lock_destroy(trData_.base.lock); pj_atomic_destroy(trData_.base.ref_cnt); RING_DBG("destroying SipIceTransport@%p", this); }
SipTransportBroker::~SipTransportBroker() { RING_DBG("~SipTransportBroker@%p", this); shutdown(); udpTransports_.clear(); transports_.clear(); RING_DBG("destroying SipTransportBroker@%p", this); }
void SipTransportBroker::transportStateChanged(pjsip_transport* tp, pjsip_transport_state state, const pjsip_transport_state_info* info) { RING_DBG("pjsip transport@%p %s -> %s", tp, tp->info, SipTransport::stateToStr(state)); // First make sure that this transport is handled by us // and remove it from any mapping if destroy pending or done. std::shared_ptr<SipTransport> sipTransport; { std::lock_guard<std::mutex> lock(transportMapMutex_); auto key = transports_.find(tp); if (key == transports_.end()) { RING_WARN("spurious pjsip transport state change"); return; } sipTransport = key->second.lock(); #if PJ_VERSION_NUM > (2 << 24 | 1 << 16) bool destroyed = state == PJSIP_TP_STATE_DESTROY; #else bool destroyed = tp->is_destroying; #endif // maps cleanup if (destroyed) { RING_DBG("unmap pjsip transport@%p {SipTransport@%p}", tp, sipTransport.get()); transports_.erase(key); // If UDP const auto type = tp->key.type; if (type == PJSIP_TRANSPORT_UDP or type == PJSIP_TRANSPORT_UDP6) { const auto updKey = std::find_if( udpTransports_.cbegin(), udpTransports_.cend(), [tp](const std::pair<SipTransportDescr, pjsip_transport*>& pair) { return pair.second == tp; }); if (updKey != udpTransports_.cend()) udpTransports_.erase(updKey); } } } // Propagate the event to the appropriate transport // Note the SipTransport may not be in our mappings if marked as dead if (sipTransport) sipTransport->stateCallback(state, info); }
void AccountFactory::removeAccount(Account& account) { const auto account_type = account.getAccountType(); std::lock_guard<std::recursive_mutex> lock(mutex_); const auto& id = account.getAccountID(); RING_DBG("Removing account %s", id.c_str()); auto& map = accountMaps_.at(account.getAccountType()); map.erase(id); RING_DBG("Remaining %zu %s account(s)", map.size(), account_type); }
int VideoInput::allocateOneBuffer(struct VideoFrameBuffer& b, int length) { b.data = std::malloc(length); if (b.data) { b.status = BUFFER_AVAILABLE; b.length = length; RING_DBG("Allocated buffer [%p]", b.data); return 0; } RING_DBG("Failed to allocate memory for one buffer"); return -ENOMEM; }
void HistoryTest::test_get_serialized() { RING_DBG("-------------------- HistoryTest::test_get_serialized --------------------\n"); bool res = history_->load(HISTORY_LIMIT); CPPUNIT_ASSERT(res); CPPUNIT_ASSERT(history_->getSerialized().size() == HISTORY_SAMPLE_SIZE); }
void HistoryTest::test_load_items() { RING_DBG("-------------------- HistoryTest::test_load_items --------------------\n"); bool res = history_->load(HISTORY_LIMIT); CPPUNIT_ASSERT(res); CPPUNIT_ASSERT(history_->numberOfItems() == HISTORY_SAMPLE_SIZE); }
void HistoryTest::test_load_from_file() { RING_DBG("-------------------- HistoryTest::test_load_from_file --------------------\n"); bool res = history_->load(HISTORY_LIMIT); CPPUNIT_ASSERT(res); }
void HistoryTest::test_create_path() { RING_DBG("-------------------- HistoryTest::test_set_path --------------------\n"); std::string path(HISTORY_SAMPLE); CPPUNIT_ASSERT(history_->path_ == path); }
bool AudioSender::setup(SocketPair& socketPair) { audioEncoder_.reset(new MediaEncoder); muxContext_.reset(socketPair.createIOContext(mtu_)); try { /* Encoder setup */ RING_DBG("audioEncoder_->openOutput %s", dest_.c_str()); audioEncoder_->setMuted(muteState_); audioEncoder_->openOutput(dest_.c_str(), args_); audioEncoder_->setInitSeqVal(seqVal_); audioEncoder_->setIOContext(muxContext_); audioEncoder_->startIO(); } catch (const MediaEncoderException &e) { RING_ERR("%s", e.what()); return false; } #ifdef DEBUG_SDP audioEncoder_->print_sdp(); #endif return true; }
std::shared_ptr<RingBuffer> RingBufferPool::createRingBuffer(const std::string& id) { std::lock_guard<std::recursive_mutex> lk(stateLock_); auto rbuf = getRingBuffer(id); if (rbuf) { RING_DBG("Ringbuffer already exists for id '%s'", id.c_str()); return rbuf; } rbuf.reset(new RingBuffer(id, SIZEBUF)); RING_DBG("Ringbuffer created with id '%s'", id.c_str()); ringBufferMap_.insert(std::make_pair(id, std::weak_ptr<RingBuffer>(rbuf))); return rbuf; }
void SIPCall::hangup(int reason) { // Stop all RTP streams stopAllMedia(); if (not inv or not inv->dlg) { removeCall(); throw VoipLinkException("No invite session for this call"); } pjsip_route_hdr *route = inv->dlg->route_set.next; while (route and route != &inv->dlg->route_set) { char buf[1024]; int printed = pjsip_hdr_print_on(route, buf, sizeof(buf)); if (printed >= 0) { buf[printed] = '\0'; RING_DBG("[call:%s] Route header %s", getCallId().c_str(), buf); } route = route->next; } const int status = reason ? reason : inv->state <= PJSIP_INV_STATE_EARLY and inv->role != PJSIP_ROLE_UAC ? PJSIP_SC_CALL_TSX_DOES_NOT_EXIST : inv->state >= PJSIP_INV_STATE_DISCONNECTED ? PJSIP_SC_DECLINE : 0; // Notify the peer terminateSipSession(status); setState(Call::ConnectionState::DISCONNECTED, reason); removeCall(); }
pjsip_route_hdr * createRouteSet(const std::string &route, pj_pool_t *hdr_pool) { pjsip_route_hdr *route_set = pjsip_route_hdr_create(hdr_pool); std::string host; int port = 0; size_t found = route.find(":"); if (found != std::string::npos) { host = route.substr(0, found); port = atoi(route.substr(found + 1, route.length() - found).c_str()); } else host = route; pjsip_route_hdr *routing = pjsip_route_hdr_create(hdr_pool); pjsip_sip_uri *url = pjsip_sip_uri_create(hdr_pool, 0); url->lr_param = 1; routing->name_addr.uri = (pjsip_uri*) url; pj_strdup2(hdr_pool, &url->host, host.c_str()); url->port = port; RING_DBG("Adding route %s", host.c_str()); pj_list_push_back(route_set, pjsip_hdr_clone(hdr_pool, routing)); return route_set; }
std::shared_ptr<SipTransport> SipTransportBroker::createUdpTransport(const SipTransportDescr& d) { RETURN_IF_FAIL(d.listenerPort != 0, nullptr, "Could not determine port for this transport"); auto family = pjsip_transport_type_get_af(d.type); IpAddr listeningAddress = (d.interface == ip_utils::DEFAULT_INTERFACE) ? ip_utils::getAnyHostAddr(family) : ip_utils::getInterfaceAddr(d.interface, family); listeningAddress.setPort(d.listenerPort); RETURN_IF_FAIL(listeningAddress, nullptr, "Could not determine IP address for this transport"); pjsip_transport *transport = nullptr; pj_status_t status = listeningAddress.isIpv4() ? pjsip_udp_transport_start (endpt_, &static_cast<const pj_sockaddr_in&>(listeningAddress), nullptr, 1, &transport) : pjsip_udp_transport_start6(endpt_, &static_cast<const pj_sockaddr_in6&>(listeningAddress), nullptr, 1, &transport); if (status != PJ_SUCCESS) { RING_ERR("pjsip_udp_transport_start* failed with error %d: %s", status, sip_utils::sip_strerror(status).c_str()); RING_ERR("UDP IPv%s Transport did not start on %s", listeningAddress.isIpv4() ? "4" : "6", listeningAddress.toString(true).c_str()); return nullptr; } RING_DBG("Created UDP transport on %s : %s", d.interface.c_str(), listeningAddress.toString(true).c_str()); auto ret = std::make_shared<SipTransport>(transport); // dec ref because the refcount starts at 1 and SipTransport increments it ? // pjsip_transport_dec_ref(transport); return ret; }
AccountFactory::AccountFactory() { auto sipfunc = [](const std::string& id){ return std::make_shared<SIPAccount>(id, true); }; generators_.insert(std::make_pair(SIPAccount::ACCOUNT_TYPE, sipfunc)); RING_DBG("registered %s account", SIPAccount::ACCOUNT_TYPE); #if HAVE_IAX auto iaxfunc = [](const std::string& id){ return std::make_shared<IAXAccount>(id); }; generators_.insert(std::make_pair(IAXAccount::ACCOUNT_TYPE, iaxfunc)); RING_DBG("registered %s account", IAXAccount::ACCOUNT_TYPE); #endif #if HAVE_DHT auto dhtfunc = [](const std::string& id){ return std::make_shared<RingAccount>(id, false); }; generators_.insert(std::make_pair(RingAccount::ACCOUNT_TYPE, dhtfunc)); RING_DBG("registered %s account", RingAccount::ACCOUNT_TYPE); #endif }
std::shared_ptr<SipTransport> SipTransportBroker::getUdpTransport(const SipTransportDescr& descr) { std::lock_guard<std::mutex> lock(transportMapMutex_); auto itp = udpTransports_.find(descr); if (itp != udpTransports_.end()) { auto it = transports_.find(itp->second); if (it != transports_.end()) { if (auto spt = it->second.lock()) { RING_DBG("Reusing transport %s", descr.toString().c_str()); return spt; } else { // Transport still exists but have not been destroyed yet. RING_WARN("Recycling transport %s", descr.toString().c_str()); auto ret = std::make_shared<SipTransport>(itp->second); it->second = ret; return ret; } } else { RING_WARN("Cleaning up UDP transport %s", descr.toString().c_str()); udpTransports_.erase(itp); } } auto ret = createUdpTransport(descr); if (ret) { udpTransports_[descr] = ret->get(); transports_[ret->get()] = ret; } return ret; }
void PortAudioLayer::init() { RING_DBG("Init PortAudioLayer"); const auto err = Pa_Initialize(); if (err != paNoError) { this->handleError(err); this->terminate(); } indexOut_ = indexRing_ = Pa_GetDefaultOutputDevice(); indexIn_ = Pa_GetDefaultInputDevice(); if (indexOut_ != paNoDevice) { const auto outputDeviceInfo = Pa_GetDeviceInfo(indexOut_); audioFormat_.nb_channels = outputDeviceInfo->maxOutputChannels; audioFormat_.sample_rate = outputDeviceInfo->defaultSampleRate; hardwareFormatAvailable(audioFormat_); } if (indexIn_ != paNoDevice) { const auto inputDeviceInfo = Pa_GetDeviceInfo(indexIn_); audioInputFormat_.nb_channels = inputDeviceInfo->maxInputChannels; audioInputFormat_.sample_rate = inputDeviceInfo->defaultSampleRate; hardwareInputFormatAvailable(audioInputFormat_); } }
void PortAudioLayer::stopStream() { if (status_ != Status::Started) return; RING_DBG("Stop PortAudio Streams"); for (int i = 0; i < Direction::End; i++) { auto err = Pa_StopStream(streams[i]); if(err != paNoError) this->handleError(err); err = Pa_CloseStream(streams[i]); if (err != paNoError) this->handleError(err); } { std::lock_guard<std::mutex> lock(mutex_); status_ = Status::Idle; } /* Flush the ring buffers */ flushUrgent(); flushMain(); }
bool AudioRecord::openFile() { #ifndef RING_UWP fileHandle_.reset(); // do it before calling fileExists() const bool doAppend = fileExists(); const int access = doAppend ? SFM_RDWR : SFM_WRITE; RING_DBG("Opening file %s with format %s", getFilename().c_str(), sndFormat_.toString().c_str()); fileHandle_.reset(new SndfileHandle (getFilename().c_str(), access, SF_FORMAT_WAV | SF_FORMAT_PCM_16, sndFormat_.nb_channels, sndFormat_.sample_rate)); // check overloaded boolean operator if (!*fileHandle_) { RING_WARN("Could not open WAV file!"); fileHandle_.reset(); return false; } if (doAppend and fileHandle_->seek(0, SEEK_END) < 0) RING_WARN("Couldn't seek to the end of the file "); return true; #else return false; #endif }
AudioRecord::AudioRecord() : sndFormat_(AudioFormat::MONO()) , filename_(createFilename()) , savePath_() , recorder_(this, Manager::instance().getRingBufferPool()) { RING_DBG("Generate filename for this call %s ", filename_.c_str()); }
void VideoInput::cleanup() { deleteDecoder(); // do it first to let a chance to last frame to be displayed detach(sink_.get()); sink_->stop(); RING_DBG("VideoInput closed"); }
void VideoInput::freeOneBuffer(struct VideoFrameBuffer& b) { RING_DBG("Free buffer [%p]", b.data); std::free(b.data); b.data = nullptr; b.length = 0; b.status = BUFFER_NOT_ALLOCATED; }
void PortAudioLayer::terminate() const { RING_DBG("PortAudioLayer terminate."); const auto err = Pa_Terminate(); if (err != paNoError) this->handleError(err); }
SipTransportBroker::SipTransportBroker(pjsip_endpoint *endpt, pj_caching_pool& cp, pj_pool_t& pool) : cp_(cp), pool_(pool), endpt_(endpt) { /*#if HAVE_DHT pjsip_transport_register_type(PJSIP_TRANSPORT_DATAGRAM, "ICE", pjsip_transport_get_default_port_for_type(PJSIP_TRANSPORT_UDP), &ice_pj_transport_type_); #endif*/ RING_DBG("SipTransportBroker@%p", this); }
/** * Make given call ID a reader of given ring buffer */ void RingBufferPool::addReaderToRingBuffer(std::shared_ptr<RingBuffer> rbuf, const std::string& call_id) { if (call_id != DEFAULT_ID and rbuf->id == call_id) RING_WARN("RingBuffer has a readoffset on itself"); rbuf->createReadOffset(call_id); readBindingsMap_[call_id].insert(rbuf); // bindings list created if not existing RING_DBG("Bind rbuf '%s' to callid '%s'", rbuf->id.c_str(), call_id.c_str()); }
void AudioRecord::initFilename(const std::string &peerNumber) { RING_DBG("Initialize audio record for peer : %s", peerNumber.c_str()); // if savePath_ don't contains filename if (savePath_.find(".wav") == std::string::npos) { filename_ = createFilename(); filename_.append("-" + sanitize(peerNumber) + "-" PACKAGE); filename_.append(".wav"); } else { filename_ = ""; } }
SipTransport::SipTransport(pjsip_transport* t) : transport_(nullptr, deleteTransport) { if (not t or pjsip_transport_add_ref(t) != PJ_SUCCESS) throw std::runtime_error("invalid transport"); // Set pointer here, right after the successful pjsip_transport_add_ref transport_.reset(t); RING_DBG("SipTransport@%p {tr=%p {rc=%ld}}", this, transport_.get(), pj_atomic_get(transport_->ref_cnt)); }
std::shared_ptr<TlsListener> SipTransportBroker::getTlsListener(const SipTransportDescr& d, const pjsip_tls_setting* settings) { RETURN_IF_FAIL(settings, nullptr, "TLS settings not specified"); auto family = pjsip_transport_type_get_af(d.type); IpAddr listeningAddress = (d.interface == ip_utils::DEFAULT_INTERFACE) ? ip_utils::getAnyHostAddr(family) : ip_utils::getInterfaceAddr(d.interface, family); listeningAddress.setPort(d.listenerPort); RETURN_IF_FAIL(listeningAddress, nullptr, "Could not determine IP address for this transport"); RING_DBG("Creating TLS listener %s on %s...", d.toString().c_str(), listeningAddress.toString(true).c_str()); #if 0 RING_DBG(" ca_list_file : %s", settings->ca_list_file.ptr); RING_DBG(" cert_file : %s", settings->cert_file.ptr); RING_DBG(" ciphers_num : %d", settings->ciphers_num); RING_DBG(" verify server %d client %d client_cert %d", settings->verify_server, settings->verify_client, settings->require_client_cert); RING_DBG(" reuse_addr : %d", settings->reuse_addr); #endif pjsip_tpfactory *listener = nullptr; const pj_status_t status = pjsip_tls_transport_start2(endpt_, settings, listeningAddress.pjPtr(), nullptr, 1, &listener); if (status != PJ_SUCCESS) { RING_ERR("TLS listener did not start: %s", sip_utils::sip_strerror(status).c_str()); return nullptr; } return std::make_shared<TlsListener>(listener); }
bool VideoInput::setup() { if (not attach(sink_.get())) { RING_ERR("attach sink failed"); return false; } if (!sink_->start()) RING_ERR("start sink failed"); RING_DBG("VideoInput ready to capture"); return true; }