void TestPlugin::initialize() { NamedList* httpdconf = 0; Output("Initializing module TestHttpBase"); Configuration cfg; cfg = Engine::configFile("httpserver"); cfg.load(); for (unsigned int i = 0; i < cfg.sections(); i++) { httpdconf = cfg.getSection(i); String name = httpdconf ? httpdconf->c_str() : ""; if (! name.startSkip("listener ",false)) continue; name.trimBlanks(); httpdconf->String::operator=(name); break; // XXX only first listener } if (m_first) m_testThread = new TestThread; m_testThread->configure(*httpdconf); if (m_first) { m_first = false; m_testThread->startup(); Engine::install(new TestHandler("http.request")); } // delete httpdconf; }
// Update RTP/SDP data from parameters // Return true if media changed bool SDPSession::updateRtpSDP(const NamedList& params) { DDebug(m_parser,DebugAll,"SDPSession::updateRtpSDP(%s) [%p]",params.c_str(),this); String addr; ObjList* tmp = updateRtpSDP(params,addr,m_rtpMedia); if (tmp) { bool chg = (m_rtpLocalAddr != addr); m_rtpLocalAddr = addr; return setMedia(tmp) || chg; } return false; }
// response = md5(md5(username:realm:password):nonce:md5(method:uri)) // qop=auth --> response = md5(md5(username:realm:password):nonce:nc:cnonce:qop:md5(method:uri)) void SIPEngine::buildAuth(const String& username, const String& realm, const String& passwd, const String& nonce, const String& method, const String& uri, String& response, const NamedList& qop) { XDebug(DebugAll,"SIP Building auth: '%s:%s:%s' '%s' '%s:%s'", username.c_str(),realm.c_str(),passwd.c_str(),nonce.c_str(),method.c_str(),uri.c_str()); MD5 m1,m2; m1 << username << ":" << realm << ":" << passwd; m2 << method << ":" << uri; String tmp; tmp << m1.hexDigest() << ":" << nonce << ":"; if (qop) { if (qop == YSTRING("auth")) tmp << qop[YSTRING("nc")] << ":" << qop[YSTRING("cnonce")] << ":" << qop.c_str() << ":"; else Debug(DebugStub,"SIPEngine::buildAuth() not implemented for qop=%s", qop.c_str()); } tmp << m2.hexDigest(); m1.clear(); m1.update(tmp); response = m1.hexDigest(); }
// Update members from a dispatched "chan.rtp" message void SDPMedia::update(const NamedList& msg, bool pickFormat) { DDebug(DebugAll,"SDPMedia::update('%s',%s) [%p]", msg.c_str(),String::boolText(pickFormat),this); m_id = msg.getValue("rtpid",m_id); m_lPort = msg.getValue("localport",m_lPort); if (pickFormat) { const char* format = msg.getValue("format"); if (format) { m_format = format; if ((m_formats != m_format) && (msg.getIntValue("remoteport") > 0)) { Debug(DebugNote,"Choosing started '%s' format '%s' [%p]", c_str(),format,this); m_formats = m_format; } } } }
// 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); }
// 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; }