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; }
// 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; }
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; }
// 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; }
// 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; }
// 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())); } }
void ExpEvaluator::dump(const ObjList& codes, String& res) const { for (const ObjList* l = codes.skipNull(); l; l = l->skipNext()) { if (res) res << " "; const ExpOperation* o = static_cast<const ExpOperation*>(l->get()); dump(*o,res); } }
bool ExpEvaluator::runEvaluate(const ObjList& opcodes, ObjList& stack, GenObject* context) const { DDebug(this,DebugInfo,"runEvaluate(%p,%p,%p)",&opcodes,&stack,context); for (const ObjList* l = opcodes.skipNull(); l; l = l->skipNext()) { const ExpOperation* o = static_cast<const ExpOperation*>(l->get()); if (!runOperation(stack,*o,context)) return false; } return true; }
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(); }
void ListIterator::assign(ObjList& list, int offset) { clear(); m_objList = &list; m_length = list.count(); if (!m_length) return; m_objects = new GenObject* [m_length]; offset = (m_length - offset) % m_length; unsigned int i = 0; for (ObjList* l = list.skipNull(); i < m_length; l = l->skipNext()) { if (!l) break; m_objects[((i++) + offset) % m_length] = l->get(); } while (i < m_length) m_objects[((i++) + offset) % m_length] = 0; }
int ExpEvaluator::evaluate(NamedList& results, unsigned int index, const char* prefix) const { ObjList stack; if (!evaluate(stack)) return -1; String idx(prefix); if (index) idx << index << "."; int column = 0; for (ObjList* r = stack.skipNull(); r; r = r->skipNext()) { column++; const ExpOperation* res = static_cast<const ExpOperation*>(r->get()); String name = res->name(); if (name.null()) name = column; results.setParam(idx+name,*res); } return column; }
// Set new media list. Return true if changed bool SDPSession::setMedia(ObjList* media) { if (media == m_rtpMedia) return false; DDebug(m_parser,DebugAll,"SDPSession::setMedia(%p) [%p]",media,this); ObjList* tmp = m_rtpMedia; m_rtpMedia = media; bool chg = m_rtpMedia != 0; if (tmp) { chg = false; for (ObjList* o = tmp->skipNull(); o; o = o->skipNext()) { SDPMedia* m = static_cast<SDPMedia*>(o->get()); if (media && m->sameAs(static_cast<SDPMedia*>((*media)[*m]),m_parser->ignorePort())) continue; chg = true; mediaChanged(*m); } TelEngine::destruct(tmp); } return chg; }
bool ExpEvaluator::runAllFields(ObjList& stack, GenObject* context) const { DDebug(this,DebugAll,"runAllFields(%p,%p)",&stack,context); bool ok = true; for (ObjList* l = stack.skipNull(); l; l = l->skipNext()) { const ExpOperation* o = static_cast<const ExpOperation*>(l->get()); if (o->barrier()) break; if (o->opcode() != OpcField) continue; ObjList tmp; if (runField(tmp,*o,context)) { ExpOperation* val = popOne(tmp); if (val) l->set(val); else ok = false; } else ok = false; } return ok; }
unsigned int TableEvaluator::evalLimit() { if (m_limitVal == (unsigned int)-2) { m_limitVal = (unsigned int)-1; // hack: use a loop so we can break out of it while (!m_limit.null()) { ObjList res; if (!m_limit.evaluate(res)) break; ObjList* first = res.skipNull(); if (!first) break; const ExpOperation* o = static_cast<const ExpOperation*>(first->get()); if (o->opcode() != ExpEvaluator::OpcPush) break; int lim = o->number(); if (lim < 0) lim = 0; m_limitVal = lim; break; } } return m_limitVal; }
// 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; }
// Create a buffer containing the byte representation of a message to be sent // and another one with the header bool ETSIModem::createMsg(NamedList& params, DataBlock& data) { int type = lookup(params,s_msg); switch (type) { case MsgCallSetup: break; case MsgMWI: case MsgCharge: case MsgSMS: Debug(this,DebugStub,"Create message '%s' not implemented [%p]", params.c_str(),this); return false; default: Debug(this,DebugNote,"Can't create unknown message '%s' [%p]", params.c_str(),this); return false; } ObjList msg; bool fail = !params.getBoolValue("force-send",true); // DateTime - ETSI EN 300 659-3 - 5.4.1 String datetime = params.getValue("datetime"); unsigned char dt[4]; bool ok = false; if (datetime.isBoolean()) if (datetime.toBoolean()) ok = getDateTime(dt); else ; else ok = getDateTime(dt,&datetime); if (ok) { DataBlock* dtParam = new DataBlock(0,10); unsigned char* d = (unsigned char*)dtParam->data(); d[0] = DateTime; d[1] = 8; // Set date and time: %.2d%.2d%.2d%.2d month:day:hour:minute for (int i = 0, j = 2; i < 4; i++, j += 2) { d[j] = '0' + dt[i] / 10; d[j+1] = '0' + dt[i] % 10; } msg.append(dtParam); } else DDebug(this,DebugInfo,"Can't set datetime parameter from '%s' [%p]", datetime.c_str(),this); // CallerId/CallerIdReason - ETSI EN 300 659-3 - 5.4.2: Max caller id 20 // Parameter is missing: append reason (default caller absence: 0x4f: unavailable) int res = appendParam(msg,params,CallerId,20,fail); if (res == -1) return false; if (!res) appendParam(msg,params,CallerIdReason,s_dict_callerAbsence,0x4f); // CallerName/CallerNameReason - ETSI EN 300 659-3 - 5.4.5: Max caller name 50 // Parameter is missing: append reason (default callername absence: 0x4f: unavailable) res = appendParam(msg,params,CallerName,50,fail); if (res == -1) return false; if (!res) appendParam(msg,params,CallerNameReason,s_dict_callerAbsence,0x4f); // Build message unsigned char len = 0; unsigned char hdr[2] = {type}; data.assign(&hdr,sizeof(hdr)); for (ObjList* o = msg.skipNull(); o; o = o->skipNext()) { DataBlock* msgParam = static_cast<DataBlock*>(o->get()); if (len + msgParam->length() > 255) { if (!fail) { Debug(this,DebugNote,"Trucating %s message length to %u bytes [%p]", params.c_str(),data.length(),this); break; } params.setParam("error","message-too-long"); return false; } len += msgParam->length(); data += *msgParam; } if (!len) { params.setParam("error","empty-message"); return false; } unsigned char* buf = ((unsigned char*)(data.data())); buf[1] = len; m_chksum = 0; for (unsigned int i = 0; i < data.length(); i++) m_chksum += buf[i]; unsigned char crcVal = 256 - (m_chksum & 0xff); FSKModem::addRaw(data,&crcVal,1); return true; }