Example #1
0
SIPEvent* SIPEngine::getEvent()
{
    Lock lock(this);
    ObjList* l = m_transList.skipNull();
    if (!l)
	return 0;
    u_int64_t time = Time::now();
    for (; l; l = l->skipNext()) {
	SIPTransaction* t = static_cast<SIPTransaction*>(l->get());
	SIPEvent* e = t->getEvent(true,time);
	if (e) {
	    DDebug(this,DebugInfo,"Got pending event %p (state %s) from transaction %p [%p]",
		e,SIPTransaction::stateName(e->getState()),t,this);
	    if (t->getState() == SIPTransaction::Invalid)
		m_transList.remove(t);
	    return e;
	}
    }
    time = Time::now();
    for (l = m_transList.skipNull(); l; l = l->skipNext()) {
	SIPTransaction* t = static_cast<SIPTransaction*>(l->get());
	SIPEvent* e = t->getEvent(false,time);
	if (e) {
	    DDebug(this,DebugInfo,"Got event %p (state %s) from transaction %p [%p]",
		e,SIPTransaction::stateName(e->getState()),t,this);
	    if (t->getState() == SIPTransaction::Invalid)
		m_transList.remove(t);
	    return e;
	}
    }
    return 0;
}
Example #2
0
void ListIterator::assign(HashList& list, int offset)
{
    clear();
    m_hashList = &list;
    m_length = list.count();
    if (!m_length)
	return;
    m_objects = new GenObject* [m_length];
    m_hashes = new unsigned int[m_length];
    offset = (m_length - offset) % m_length;
    unsigned int i = 0;
    for (unsigned int n = 0; n < list.length(); n++) {
	ObjList* l = list.getList(n);
	if (!l)
	    continue;
	for (l = l->skipNull(); i < m_length; l = l->skipNext()) {
	    if (!l)
		break;
	    unsigned int idx = ((i++) + offset) % m_length;
	    m_objects[idx] = l->get();
	    m_hashes[idx] = l->get()->toString().hash();
	}
    }
    while (i < m_length)
	m_objects[((i++) + offset) % m_length] = 0;
}
Example #3
0
// Convert this message to a string representation
void MGCPMessage::toString(String& dest) const
{
    // Construct first line
    dest << name() << " " << transactionId();
    if (isCommand())
	dest << " " << endpointId() << " " << m_version;
    else if (m_comment)
	dest << " " << m_comment;
    dest << "\r\n";

    // Append message parameters
    unsigned int n = params.count();
    for (unsigned int i = 0; i < n; i++) {
	NamedString* ns = params.getParam(i);
	if (!ns)
	    continue;
	dest << ns->name() << ": " << *ns << "\r\n";
    }

    // Append SDP(s)
    for (ObjList* obj = sdp.skipNull(); obj; obj = obj->skipNext()) {
	String s;
	MimeSdpBody* tmp = static_cast<MimeSdpBody*>(obj->get());
	for (ObjList* o = tmp->lines().skipNull(); o; o = o->skipNext()) {
	    NamedString* ns = static_cast<NamedString*>(o->get());
	    if (*ns)
		s << ns->name() << "=" << *ns << "\r\n";
	}
	if (s)
	    dest << "\r\n" << s;
    }
}
Example #4
0
// Insert a record into a list in the proper location
// Order records ascending by their order
// Look at ascPref for records with the same order
bool DnsRecord::insert(ObjList& list, DnsRecord* rec, bool ascPref)
{
    if (!rec || list.find(rec))
	return false;
    XDebug(DebugAll,"DnsRecord::insert(%p) order=%d pref=%d",rec,rec->order(),rec->pref());
    ObjList* o = list.skipNull();
    for (; o; o = o->skipNext()) {
	DnsRecord* crt = static_cast<DnsRecord*>(o->get());
	if (rec->order() > crt->order())
	    continue;
	if (rec->order() == crt->order()) {
	    for (; o; o = o->skipNext()) {
		DnsRecord* crt = static_cast<DnsRecord*>(o->get());
		if (crt->order() != rec->order())
		    break;
		if (crt->pref() == rec->pref())
		    continue;
		if (ascPref == (rec->pref() < crt->pref()))
		    break;
	    }
	}
	break;
    }
    if (o)
	o->insert(rec);
    else
	list.append(rec);
    return true;
}
Example #5
0
// Utility: print the result of dns query
// Return the code
static int printResult(int type, int code, const char* dname, ObjList& result, String* error)
{
#ifdef DEBUG
    if (!code) {
	String s;
	int crt = 0;
	for (ObjList* o = result.skipNull(); o; o = o->skipNext()) {
	    DnsRecord* rec = static_cast<DnsRecord*>(o->get());
	    if (!s)
		s << "\r\n-----";
	    s << "\r\n" << ++crt << ":";
	    rec->dump(s);
	}
	if (s)
	    s << "\r\n-----";
	Debug(DebugAll,"%s query for '%s' got %d records%s",
	    lookup(type,Resolver::s_types),dname,result.count(),s.safe());
    }
    else {
	String dummy;
	if (!error) {
	    error = &dummy;
#ifdef _WINDOWS
	    Thread::errorString(dummy,code);
#elif defined(__NAMESER)
	    dummy = hstrerror(code);
#endif
	}
	Debug(DebugNote,"%s query for '%s' failed with code %d error=%s",
	    lookup(type,Resolver::s_types),dname,code,TelEngine::c_safe(error));
    }
#endif
    return code;
}
Example #6
0
bool HashList::resync()
{
    XDebug(DebugAll,"HashList::resync() [%p]",this);
    bool moved = false;
    for (unsigned int n = 0; n < m_size; n++) {
        ObjList* l = m_lists[n];
        while (l) {
            GenObject* obj = l->get();
            if (obj) {
                unsigned int i = obj->toString().hash() % m_size;
                if (i != n) {
                    bool autoDel = l->autoDelete();
                    m_lists[n]->remove(obj,false);
                    if (!m_lists[i])
                        m_lists[i] = new ObjList;
                    m_lists[i]->append(obj)->setDelete(autoDel);
                    moved = true;
                    continue;
                }
            }
            l = l->next();
        }
    }
    return moved;
}
Example #7
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;
}
Example #8
0
String ExpEvaluator::dump() const
{
    String res;
    for (ObjList* l = m_opcodes.skipNull(); l; l = l->skipNext()) {
        const ExpOperation* o = static_cast<const ExpOperation*>(l->get());
        const char* oper = getOperator(o->opcode());
        if (oper) {
            res << " " << oper;
            continue;
        }
        switch (o->opcode()) {
        case OpcPush:
            if (o->number())
                res << " " << (int)o->number();
            else
                res << " '" << *o << "'";
            break;
        case OpcField:
            res << " " << o->name();
            break;
        case OpcFunc:
            res << " " << o->name() << "(" << (int)o->number() << ")";
            break;
        default:
            res << " [" << o->opcode() << "]";
        }
    }
    return res;
}
Example #9
0
GenObject* ObjList::remove(bool delobj)
{
    GenObject *tmp = m_obj;

    if (m_next) {
	ObjList *n = m_next;
	m_next = n->next();
	m_obj = n->get();
	m_delete = n->m_delete;
	n->m_obj = 0;
	n->m_next = 0;
	n->destruct();
    }
    else
	m_obj = 0;

    if (delobj && tmp) {
	XDebug(DebugInfo,"ObjList::remove() deleting %p",tmp);
	// Don't use TelEngine::destruct(): the compiler will call the non-template
	// function (which doesn't reset the pointer)
	tmp->destruct();
	tmp = 0;
    }
    return tmp;
}
Example #10
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;
}
Example #11
0
void RTPGroup::run()
{
    DDebug(DebugInfo,"RTPGroup::run() [%p]",this);
    bool ok = true;
    while (ok) {
	unsigned long msec = m_sleep;
	if (msec < s_sleep)
	    msec = s_sleep;
	lock();
	Time t;
	ObjList* l = &m_processors;
	m_listChanged = false;
	for (ok = false;l;l = l->next()) {
	    RTPProcessor* p = static_cast<RTPProcessor*>(l->get());
	    if (p) {
		ok = true;
		p->timerTick(t);
		// the list is protected from other threads but can be changed
		//  from this one so if it happened we just break out and try
		//  again later rather than using an expensive ListIterator
		if (m_listChanged)
		    break;
	    }
	}
	unlock();
	Thread::msleep(msec,true);
    }
    DDebug(DebugInfo,"RTPGroup::run() ran out of processors [%p]",this);
}
Example #12
0
// Copy a SrvRecord list into another one
void SrvRecord::copy(ObjList& dest, const ObjList& src)
{
    dest.clear();
    for (ObjList* o = src.skipNull(); o; o = o->skipNext()) {
	SrvRecord* rec = static_cast<SrvRecord*>(o->get());
	dest.append(new SrvRecord(rec->order(),rec->pref(),rec->address(),rec->port()));
    }
}
Example #13
0
void Socket::timerTick(const Time& when)
{
    for (ObjList* l = &m_filters; l; l = l->next()) {
	SocketFilter* filter = static_cast<SocketFilter*>(l->get());
	if (filter)
	    filter->timerTick(when);
    }
}
Example #14
0
ExpEvaluator::ExpEvaluator(const ExpEvaluator& original)
    : m_operators(original.m_operators), m_extender(0)
{
    extender(original.extender());
    for (ObjList* l = original.m_opcodes.skipNull(); l; l = l->skipNext()) {
        const ExpOperation* o = static_cast<const ExpOperation*>(l->get());
        m_opcodes.append(new ExpOperation(*o));
    }
}
Example #15
0
void RTPGroup::cleanup()
{
    DDebug(DebugInfo,"RTPGroup::cleanup() [%p]",this);
    lock();
    m_listChanged = true;
    ObjList* l = &m_processors;
    while (l) {
	RTPProcessor* p = static_cast<RTPProcessor*>(l->get());
	if (p) {
	    p->group(0);
	    if (p != static_cast<RTPProcessor*>(l->get()))
		continue;
	}
	l = l->next();
    }
    m_processors.clear();
    unlock();
}
Example #16
0
ExpOperation* ExpEvaluator::popOne(ObjList& stack)
{
    GenObject* o = 0;
    for (ObjList* l = stack.skipNull(); l; l=l->skipNext())
        o = l->get();
    stack.remove(o,false);
    DDebug(DebugInfo,"Popped: %p",o);
    return static_cast<ExpOperation*>(o);
}
Example #17
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));
}
Example #18
0
ExpEvaluator::ExpEvaluator(const ExpEvaluator& original)
    : m_operators(original.m_operators), m_unaryOps(original.unaryOps()),
      m_inError(false), m_lineNo(original.lineNumber()), m_extender(0)
{
    extender(original.extender());
    for (ObjList* l = original.m_opcodes.skipNull(); l; l = l->skipNext()) {
	const ExpOperation* o = static_cast<const ExpOperation*>(l->get());
	m_opcodes.append(o->clone());
    }
}
Example #19
0
bool ExpEvaluator::runEvaluate(ObjList& stack) const
{
    DDebug(DebugInfo,"runEvaluate(%p)",&stack);
    for (ObjList* l = m_opcodes.skipNull(); l; l = l->skipNext()) {
        const ExpOperation* o = static_cast<const ExpOperation*>(l->get());
        if (!runOperation(stack,*o))
            return false;
    }
    return true;
}
Example #20
0
CallInfo* CallList::find(const CallEndpoint* call)
{
    ObjList* l = m_calls.skipNull();
    for (; l; l = l->skipNext()) {
        CallInfo* info = static_cast<CallInfo*>(l->get());
        if (info->call() == call)
            return info;
    }
    return 0;
}
Example #21
0
ToneConsumer::ToneConsumer(const String& id, const String& name)
    : m_id(id), m_name(name), m_mode(Mono),
      m_detFax(true), m_detCont(false), m_detDtmf(true), m_detDnis(false),
      m_fax(s_paramsCNG), m_cont(s_paramsCOTv)
{ 
    Debug(&plugin,DebugAll,"ToneConsumer::ToneConsumer(%s,'%s') [%p]",
	id.c_str(),name.c_str(),this);
    for (int i = 0; i < 4; i++) {
	m_dtmfL[i].assign(s_paramsDtmfL[i]);
	m_dtmfH[i].assign(s_paramsDtmfH[i]);
    }
    init();
    String tmp = name;
    tmp.startSkip("tone/",false);
    if (tmp.startSkip("mixed/",false))
	m_mode = Mixed;
    else if (tmp.startSkip("left/",false))
	m_mode = Left;
    else if (tmp.startSkip("right/",false))
	m_mode = Right;
    else tmp.startSkip("mono/",false);
    if (m_mode != Mono)
	m_format = "2*slin";
    if (tmp && (tmp != "*")) {
	// individual detection requested
	m_detFax = m_detCont = m_detDtmf = m_detDnis = false;
	ObjList* k = tmp.split(',',false);
	for (ObjList* l = k; l; l = l->next()) {
	    String* s = static_cast<String*>(l->get());
	    if (!s)
		continue;
	    m_detFax = m_detFax || (*s == "fax");
	    m_detCont = m_detCont || (*s == "cotv");
	    m_detDtmf = m_detDtmf || (*s == "dtmf");
	    if (*s == "rfax") {
		// detection of receiving Fax requested
		m_fax.assign(s_paramsCED);
		m_detFax = true;
	    }
	    else if (*s == "cots") {
		// detection of COT Send tone requested
		m_cont.assign(s_paramsCOTs);
		m_detCont = true;
	    }
	    else if (*s == "callsetup") {
		// call setup info in the form *ANI*DNIS*
		m_detDnis = true;
	    }
	}
	TelEngine::destruct(k);
    }
    s_mutex.lock();
    s_count++;
    s_mutex.unlock();
}
Example #22
0
//  Find the info object associated with a remote peer by alias name
MGCPEpInfo* MGCPEndpoint::findAlias(const String& alias)
{
    if (alias.null())
	return 0;
    Lock lock(this);
    for (ObjList* o = m_remote.skipNull(); o; o = o->skipNext()) {
	MGCPEpInfo* info = static_cast<MGCPEpInfo*>(o->get());
	if (alias == info->alias)
	    return info;
    }
    return 0;
}
Example #23
0
void CallEndpoint::destroyed()
{
#ifdef DEBUG
    ObjList* l = m_data.skipNull();
    for (; l; l=l->skipNext()) {
	DataEndpoint* e = static_cast<DataEndpoint*>(l->get());
	Debug(DebugAll,"Endpoint at %p type '%s' refcount=%d",e,e->name().c_str(),e->refcount());
    }
#endif
    disconnect(true,0,true);
    m_data.clear();
}
Example #24
0
// Try to start RTP for all media
bool SDPSession::startRtp(RefObject* context)
{
    if (m_rtpForward || !m_rtpMedia || (m_mediaStatus != MediaStarted))
	return false;
    DDebug(m_parser,DebugAll,"SDPSession::startRtp(%p) [%p]",context,this);
    bool ok = false;
    for (ObjList* o = m_rtpMedia->skipNull(); o; o = o->skipNext()) {
	SDPMedia* m = static_cast<SDPMedia*>(o->get());
	ok = dispatchRtp(m,m_rtpAddr,true,false,context) || ok;
    }
    return ok;
}
Example #25
0
SIPTransaction* SIPEngine::addMessage(SIPMessage* message)
{
    DDebug(this,DebugInfo,"addMessage(%p) [%p]",message,this);
    if (!message)
	return 0;
    // make sure outgoing messages are well formed
    if (message->isOutgoing())
	message->complete(this);
    // locate the branch parameter of last Via header - added by the UA
    const MimeHeaderLine* hl = message->getLastHeader("Via");
    if (!hl)
#ifdef SIP_STRICT
	return 0;
#else
	Debug(this,DebugMild,"Received message with no Via header! (sender bug)");
#endif
    const NamedString* br = hl ? hl->getParam("branch") : 0;
    String branch;
    if (br && br->startsWith("z9hG4bK"))
	branch = *br;
    Lock lock(this);
    SIPTransaction* forked = 0;
    ObjList* l = &m_transList;
    for (; l; l = l->next()) {
	SIPTransaction* t = static_cast<SIPTransaction*>(l->get());
	if (!t)
	    continue;
	switch (t->processMessage(message,branch)) {
	    case SIPTransaction::Matched:
		return t;
	    case SIPTransaction::NoDialog:
		forked = t;
		break;
	    case SIPTransaction::NoMatch:
	    default:
		break;
	}
    }
    if (forked)
	return forkInvite(message,forked);

    if (message->isAnswer()) {
	Debug(this,DebugInfo,"Message %p was an unhandled answer [%p]",message,this);
	return 0;
    }
    if (message->isACK()) {
	DDebug(this,DebugAll,"Message %p was an unhandled ACK [%p]",message,this);
	return 0;
    }
    message->complete(this);
    return new SIPTransaction(message,this,message->isOutgoing());
}
Example #26
0
bool TableEvaluator::evalWhere()
{
    if (m_where.null())
        return true;
    ObjList res;
    if (!m_where.evaluate(res))
        return false;
    ObjList* first = res.skipNull();
    if (!first)
        return false;
    const ExpOperation* o = static_cast<const ExpOperation*>(first->get());
    return (o->opcode() == ExpEvaluator::OpcPush) && o->number();
}
Example #27
0
bool Socket::applyFilters(void* buffer, int length, int flags, const struct sockaddr* addr, socklen_t adrlen)
{
    if ((length <= 0) || !buffer)
	return false;
    if (!addr)
	adrlen = 0;
    for (ObjList* l = &m_filters; l; l = l->next()) {
	SocketFilter* filter = static_cast<SocketFilter*>(l->get());
	if (filter && filter->received(buffer,length,flags,addr,adrlen))
	    return true;
    }
    return false;
}
Example #28
0
bool CallEndpoint::connect(CallEndpoint* peer, const char* reason, bool notify)
{
    if (!peer) {
	disconnect(reason,notify);
	return false;
    }
    if (peer == m_peer)
	return true;
    if (peer == this) {
	Debug(DebugWarn,"CallEndpoint '%s' trying to connect to itself! [%p]",m_id.c_str(),this);
	return false;
    }
    DDebug(DebugAll,"CallEndpoint '%s' connecting peer %p to [%p]",m_id.c_str(),peer,this);

#if 0
    if (!s_mutex.lock(5000000)) {
	Debug(DebugFail,"Call connect failed - deadlock on call endpoint mutex!");
	Engine::restart(0);
	return false;
    }
#endif

    // are we already dead?
    if (!ref())
	return false;
    disconnect(reason,notify);
    // is our intended peer dead?
    if (!peer->ref()) {
	deref();
	return false;
    }
    peer->disconnect(reason,notify);

    ObjList* l = m_data.skipNull();
    for (; l; l=l->skipNext()) {
	DataEndpoint* e = static_cast<DataEndpoint*>(l->get());
	e->connect(peer->getEndpoint(e->name()));
    }

    m_peer = peer;
    peer->setPeer(this,reason,notify);
    connected(reason);

#if 0
    s_mutex.unlock();
#endif

    return true;
}
Example #29
0
ObjList* ObjList::append(const GenObject* obj, bool compact)
{
#ifdef XDEBUG
    Debugger debug("ObjList::append","(%p,%d) [%p]",obj,compact,this);
#endif
    ObjList *n = last();
    if (n->get() || !compact) {
	n->m_next = new ObjList();
	n = n->m_next;
    }
    else
	n->m_delete = true;
    n->set(obj);
    return n;
}
Example #30
0
void ExpEvaluator::addOpcode(ExpEvaluator::Opcode oper)
{
    DDebug(DebugAll,"addOpcode %u",oper);
    if (oper == OpcAs) {
        // the second operand is used just for the field name
        ExpOperation* o = 0;
        for (ObjList* l = m_opcodes.skipNull(); l; l=l->skipNext())
            o = static_cast<ExpOperation*>(l->get());
        if (o && (o->opcode() == OpcField)) {
            o->m_opcode = OpcPush;
            o->String::operator=(o->name());
        }
    }
    m_opcodes.append(new ExpOperation(oper));
}