Exemple #1
0
// Update members with data taken from a SDP, return true if something changed
bool SDPMedia::update(const char* formats, int rport, int lport, bool force)
{
    DDebug(DebugAll,"SDPMedia::update('%s',%d,%d,%s) [%p]",
	formats,rport,lport,String::boolText(force),this);
    bool chg = false;
    String tmp(formats);
    if (tmp && (m_formats != tmp)) {
	if (tmp.find(',') < 0) {
	    // single format received, check if acceptable
	    if (m_formats && !force && m_formats.find(tmp) < 0) {
		Debug(DebugNote,"Not changing to '%s' from '%s' [%p]",
		    formats,m_formats.c_str(),this);
		tmp.clear();
	    }
	}
	else if (m_formats && !force) {
	    // from received list keep only already offered formats
	    ObjList* l1 = tmp.split(',',false);
	    ObjList* l2 = m_formats.split(',',false);
	    for (ObjList* fmt = l1->skipNull(); fmt; ) {
		if (l2->find(fmt->get()->toString()))
		    fmt = fmt->skipNext();
		else {
		    fmt->remove();
		    fmt = fmt->skipNull();
		}
	    }
	    tmp.clear();
	    tmp.append(l1,",");
	    TelEngine::destruct(l1);
	    TelEngine::destruct(l2);
	    if (tmp.null())
		Debug(DebugNote,"Not changing formats '%s' [%p]",m_formats.c_str(),this);
	}
	if (tmp && (m_formats != tmp)) {
	    chg = true;
	    m_formats = tmp;
	    int q = m_formats.find(',');
	    m_format = m_formats.substr(0,q);
	    Debug(DebugInfo,"Choosing offered '%s' format '%s' [%p]",
		c_str(),m_format.c_str(),this);
	}
    }
    if (rport >= 0) {
	tmp = rport;
	if (m_rPort != tmp) {
	    chg = true;
	    m_rPort = tmp;
	}
    }
    if (lport >= 0) {
	tmp = lport;
	if (m_lPort != tmp) {
	    m_localChanged = true;
	    chg = true;
	    m_lPort = tmp;
	}
    }
    return chg;
}
Exemple #2
0
unsigned int ObjVector::assign(ObjList& list, bool move, unsigned int maxLen)
{
    if (!maxLen)
	maxLen = list.count();
    clear();
    if (maxLen) {
	m_objects = new GenObject*[maxLen];
	ObjList* l = list.skipNull();
	for (unsigned int i = 0; i < maxLen; i++) {
	    if (l) {
		if (move) {
		    m_objects[i] = l->remove(false);
		    l = l->skipNull();
		}
		else {
		    m_objects[i] = l->get();
		    l = l->skipNext();
		}
	    }
	    else
		m_objects[i] = 0;
	}
	m_length = maxLen;
    }
    return maxLen;
}
Exemple #3
0
GenObject* HashList::remove(GenObject* obj, bool delobj, bool useHash)
{
    ObjList* n = 0;
    if (useHash && obj)
        n = find(obj,obj->toString().hash());
    else
        n = find(obj);
    return n ? n->remove(delobj) : 0;
}
Exemple #4
0
ExpOperation* ExpEvaluator::popOpcode()
{
    ObjList* l = &m_opcodes;
    for (ObjList* p = l; p; p = p->next()) {
	if (p->get())
	    l = p;
    }
    return static_cast<ExpOperation*>(l->remove(false));
}
Exemple #5
0
// Remove a specific parameter
NamedList& NamedList::clearParam(NamedString* param, bool delParam)
{
    if (!param)
	return *this;
    ObjList* o = m_params.find(param);
    if (o)
	o->remove(delParam);
    XDebug(DebugInfo,"NamedList::clearParam(%p) found=%p",param,o);
    return *this;
}
Exemple #6
0
MrcpConnection::~MrcpConnection()
{
    s_mutex.lock();
    s_conns.remove(this,false);
    s_mutex.unlock();
    if (m_socket) {
	m_socket->terminate();
	delete m_socket;
	m_socket = 0;
    }
}
Exemple #7
0
ThreadPrivate::~ThreadPrivate()
{
#ifdef DEBUG
    Debugger debug("ThreadPrivate::~ThreadPrivate()"," %p '%s' [%p]",m_thread,m_name,this);
#endif
    m_running = false;
    Lock lock(s_tmutex);
    s_threads.remove(this,false);
    if (m_thread && m_updest) {
	Thread *t = m_thread;
	m_thread = 0;
	// let other threads access the list while we delete our upper layer
	lock.drop();
	delete t;
    }
}
Exemple #8
0
NamedList& NamedList::clearParam(const String& name, char childSep)
{
    XDebug(DebugInfo,"NamedList::clearParam(\"%s\",'%.1s')",
	name.c_str(),&childSep);
    String tmp;
    if (childSep)
	tmp << name << childSep;
    ObjList *p = &m_params;
    while (p) {
        NamedString *s = static_cast<NamedString *>(p->get());
        if (s && ((s->name() == name) || s->name().startsWith(tmp)))
            p->remove();
	else
	    p = p->next();
    }
    return *this;
}
Exemple #9
0
// Repeatedly calls dispatchRtp() for each media in the list
// Update it on success. Remove it on failure
bool SDPSession::dispatchRtp(const char* addr, bool start, RefObject* context)
{
    if (!m_rtpMedia)
	return false;
    DDebug(m_parser,DebugAll,"SDPSession::dispatchRtp(%s,%u,%p) [%p]",
	addr,start,context,this);
    bool ok = false;
    ObjList* o = m_rtpMedia->skipNull();
    while (o) {
	SDPMedia* m = static_cast<SDPMedia*>(o->get());
	if (dispatchRtp(m,addr,start,true,context)) {
	    ok = true;
	    o = o->skipNext();
	}
	else {
	    Debug(m_parser,DebugMild,
		"Removing failed SDP media '%s' format '%s' from offer [%p]",
		m->c_str(),m->format().safe(),this);
	    o->remove();
	    o = o->skipNull();
	}
    }
    return ok;
}
Exemple #10
0
GenObject* ObjList::remove(GenObject* obj, bool delobj)
{
    ObjList *n = find(obj);
    return n ? n->remove(delobj) : 0;
}
Exemple #11
0
// Update from parameters. Build a default SDP if no media is found in params
bool SDPSession::updateSDP(const NamedList& params)
{
    DDebug(m_parser,DebugAll,"SDPSession::updateSdp('%s') [%p]",params.c_str(),this);
    bool defaults = true;
    const char* sdpPrefix = params.getValue("osdp-prefix","osdp");
    ObjList* lst = 0;
    unsigned int n = params.length();
    String defFormats;
    m_parser->getAudioFormats(defFormats);
    for (unsigned int i = 0; i < n; i++) {
	const NamedString* p = params.getParam(i);
	if (!p)
	    continue;
	// search for rtp_port or rtp_port_MEDIANAME parameters
	String tmp(p->name());
	if (!tmp.startSkip("media",false))
	    continue;
	if (tmp && (tmp[0] != '_'))
	    continue;
	// since we found at least one media declaration disable defaults
	defaults = false;
	// now tmp holds the suffix for the media, null for audio
	bool audio = tmp.null();
	// check if media is supported, default only for audio
	if (!p->toBoolean(audio))
	    continue;
	String fmts = params.getValue("formats" + tmp);
	if (audio && fmts.null())
	    fmts = defFormats;
	if (fmts.null())
	    continue;
	String trans = params.getValue("transport" + tmp,"RTP/AVP");
	String crypto;
	if (m_secure)
	    crypto = params.getValue("crypto" + tmp);
	if (audio)
	    tmp = "audio";
	else
	    tmp >> "_";
	SDPMedia* rtp = 0;
	// try to take the media descriptor from the old list
	if (m_rtpMedia) {
	    ObjList* om = m_rtpMedia->find(tmp);
	    if (om)
		rtp = static_cast<SDPMedia*>(om->remove(false));
	}
	bool append = false;
	if (rtp)
	    rtp->update(fmts);
	else {
	    rtp = new SDPMedia(tmp,trans,fmts);
	    append = true;
	}
	rtp->crypto(crypto,false);
	if (sdpPrefix) {
	    for (unsigned int j = 0; j < n; j++) {
		const NamedString* param = params.getParam(j);
		if (!param)
		    continue;
		tmp = param->name();
		if (tmp.startSkip(sdpPrefix + rtp->suffix() + "_",false) && (tmp.find('_') < 0))
		    rtp->parameter(tmp,*param,append);
	    }
	}
	if (!lst)
	    lst = new ObjList;
	lst->append(rtp);
    }
    if (defaults && !lst) {
	lst = new ObjList;
	lst->append(new SDPMedia("audio","RTP/AVP",params.getValue("formats",defFormats)));
    }
    return setMedia(lst);
}
Exemple #12
0
GenObject* ObjList::remove(const String& str, bool delobj)
{
    ObjList *n = find(str);
    return n ? n->remove(delobj) : 0;
}
Exemple #13
0
void ThreadPrivate::killall()
{
    Debugger debug("ThreadPrivate::killall()");
    ThreadPrivate *t;
    bool sledgehammer = false;
    s_tmutex.lock();
    ThreadPrivate* crt = ThreadPrivate::current();
    int c = s_threads.count();
    if (crt)
	Debug(DebugNote,"Thread '%s' is soft cancelling other %d running threads",crt->m_name,c-1);
    else
	Debug(DebugNote,"Soft cancelling %d running threads",c);
    ObjList* l = &s_threads;
    while (l && (t = static_cast<ThreadPrivate *>(l->get())) != 0)
    {
	if (t != crt) {
	    Debug(DebugInfo,"Stopping ThreadPrivate '%s' [%p]",t->m_name,t);
	    t->cancel(false);
	}
	l = l->next();
    }
    for (int w = 0; w < SOFT_WAITS; w++) {
	s_tmutex.unlock();
	Thread::idle();
	s_tmutex.lock();
	c = s_threads.count();
	// ignore the current thread if we have one
	if (crt && c)
	    c--;
	if (!c) {
	    s_tmutex.unlock();
	    return;
	}
    }
    Debug(DebugMild,"Hard cancelling %d remaining threads",c);
    l = &s_threads;
    c = 1;
    while (l && (t = static_cast<ThreadPrivate *>(l->get())) != 0)
    {
	if (t == crt) {
	    l = l->next();
	    continue;
	}
	Debug(DebugInfo,"Trying to kill ThreadPrivate '%s' [%p], attempt %d",t->m_name,t,c);
	bool ok = t->cancel(true);
	if (ok) {
	    int d = 0;
	    // delay a little (exponentially) so threads have a chance to clean up
	    for (int i=1; i<=KILL_WAIT; i<<=1) {
		s_tmutex.unlock();
		Thread::msleep(i-d);
		d = i;
		s_tmutex.lock();
		if (t != l->get())
		    break;
	    }
	}
	if (t != l->get())
	    c = 1;
	else {
	    if (ok) {
#ifdef _WINDOWS
		Debug(DebugGoOn,"Could not kill %p but seems OK to delete it (library bug?)",t);
		s_tmutex.unlock();
		t->destroy();
		s_tmutex.lock();
		if (t != l->get())
		    c = 1;
#else
		Debug(DebugGoOn,"Could not kill cancelled %p so we'll abandon it (library bug?)",t);
		l->remove(t,false);
		c = 1;
#endif
		continue;
	    }
	    Thread::msleep(1);
	    if (++c >= HARD_KILLS) {
		Debug(DebugGoOn,"Could not kill %p, will use sledgehammer later.",t);
		sledgehammer = true;
		t->m_thread = 0;
		l = l->next();
		c = 1;
	    }
	}
    }
    s_tmutex.unlock();
    // last solution - a REALLY BIG tool!
    // usually too big since many libraries have threads of their own...
    if (sledgehammer) {
#ifdef THREAD_KILL
	Debug(DebugGoOn,"Brutally killing remaining threads!");
	::pthread_kill_other_threads_np();
#else
	Debug(DebugGoOn,"Aargh! I cannot kill remaining threads on this platform!");
#endif
    }
}