Example #1
0
// Put the list of net media in a parameter list
void SDPSession::putMedia(NamedList& msg, ObjList* mList, bool putPort)
{
    if (!mList)
	return;
    bool audio = false;
    bool other = false;
    for (mList = mList->skipNull(); mList; mList = mList->skipNext()) {
	SDPMedia* m = static_cast<SDPMedia*>(mList->get());
	m->putMedia(msg,putPort);
	if (m->isAudio())
	    audio = true;
	else
	    other = true;
    }
    if (other && !audio)
	msg.setParam("media",String::boolText(false));
}
Example #2
0
// Creates a SDP body from transport address and list of media descriptors
// Use own list if given media list is 0
MimeSdpBody* SDPSession::createSDP(const char* addr, ObjList* mediaList)
{
    DDebug(m_enabler,DebugAll,"SDPSession::createSDP('%s',%p) [%p]",addr,mediaList,m_ptr);
    if (!mediaList)
        mediaList = m_rtpMedia;
    // if we got no media descriptors we simply create no SDP
    if (!mediaList)
        return 0;
    if (m_sdpSession)
        ++m_sdpVersion;
    else
        m_sdpVersion = m_sdpSession = Time::secNow();

    // override the address with the externally advertised if needed
    if (addr && m_rtpNatAddr)
        addr = m_rtpNatAddr;
    if (!m_originAddr)
        m_originAddr = addr ? addr : m_host.safe();
    // no address means on hold or muted
    String origin;
    origin << "yate " << m_sdpSession << " " << m_sdpVersion;
    origin << " ";
    int f = addIP(origin,m_originAddr);
    String conn;
    addIP(conn,addr,f);

    MimeSdpBody* sdp = new MimeSdpBody;
    sdp->addLine("v","0");
    sdp->addLine("o",origin);
    sdp->addLine("s",m_parser->m_sessionName);
    sdp->addLine("c",conn);
    sdp->addLine("t","0 0");

    Lock lock(m_parser);
    bool defcodecs = m_parser->m_codecs.getBoolValue("default",true);
    for (ObjList* ml = mediaList->skipNull(); ml; ml = ml->skipNext()) {
        SDPMedia* m = static_cast<SDPMedia*>(ml->get());
        int rfc2833 = 0;
        if ((m_rfc2833 >= 0) && m->isAudio()) {
            if (!m_rtpForward) {
                rfc2833 = m->rfc2833().toInteger(m_rfc2833);
                if (rfc2833 < 96 || rfc2833 > 127)
                    rfc2833 = 101;
            }
            else if (m->rfc2833().toBoolean(true)) {
                rfc2833 = m->rfc2833().toInteger();
                if (rfc2833 < 96 || rfc2833 > 127)
                    rfc2833 = 0;
            }
        }
        String mline(m->fmtList());
        ObjList* l = mline.split(',',false);
        mline = *m;
        mline << " " << (m->localPort() ? m->localPort().c_str() : "0") << " " << m->transport();
        ObjList* map = m->mappings().split(',',false);
        ObjList rtpmap;
        ObjList* dest = &rtpmap;
        String frm;
        int ptime = 0;
        ObjList* f = l;
        for (; f; f = f->next()) {
            const String* s = static_cast<const String*>(f->get());
            if (s) {
                int mode = 0;
                if (*s == "g729b")
                    continue;
                int payload = s->toInteger(SDPParser::s_payloads,-1);
                int defcode = payload;
                String tmp = *s;
                tmp << "=";
                bool found = false;
                for (ObjList* pl = map; pl; pl = pl->next()) {
                    const String* mapping = static_cast<const String*>(pl->get());
                    if (!mapping)
                        continue;
                    if (mapping->startsWith(tmp)) {
                        payload = -1;
                        tmp = *mapping;
                        tmp >> "=" >> payload;
                        found = true;
                        XDebug(m_enabler,DebugAll,"RTP mapped payload %d for '%s' [%p]",
                               payload,s->c_str(),m_ptr);
                        break;
                    }
                    String tmp2 = *mapping;
                    int pload;
                    tmp2 >> "=" >> pload;
                    if (payload == pload) {
                        XDebug(m_enabler,DebugAll,"RTP conflict for payload %d, allocating new [%p]",
                               payload,m_ptr);
                        payload = -1;
                        u_int32_t bmap = 0;
                        for (ObjList* sl = map; sl; sl = sl->next()) {
                            mapping = static_cast<const String*>(sl->get());
                            if (!mapping)
                                continue;
                            tmp2 = *mapping;
                            pload = 0;
                            tmp2 >> "=" >> pload;
                            if (pload >= 96 && pload < 127)
                                bmap |= 1 << (pload - 96);
                        }
                        // allocate free and non-standard is possible
                        for (pload = 96; pload < 127; pload++) {
                            if (pload == rfc2833)
                                continue;
                            if (lookup(pload,SDPParser::s_rtpmap))
                                continue;
                            if ((bmap & (1 << (pload - 96))) == 0) {
                                payload = pload;
                                break;
                            }
                        }
                        if (payload >= 0)
                            break;
                        // none free, allocate from "standard" ones too
                        for (pload = 96; pload < 127; pload++) {
                            if (pload == rfc2833)
                                continue;
                            if ((bmap & (1 << (pload - 96))) == 0) {
                                payload = pload;
                                break;
                            }
                        }
                        break;
                    }
                }
                if (payload >= 0) {
                    if (!found) {
                        tmp = *s;
                        tmp << "=" << payload;
                        map->append(new String(tmp));
                    }
                    if (defcode < 0)
                        defcode = payload;
                    const char* map = lookup(defcode,SDPParser::s_rtpmap);
                    if (map && m_parser->m_codecs.getBoolValue(*s,defcodecs && DataTranslator::canConvert(*s))) {
                        if (*s == "ilbc20")
                            ptime = mode = 20;
                        else if (*s == "ilbc30")
                            ptime = mode = 30;
                        frm << " " << payload;
                        String* temp = new String("rtpmap:");
                        *temp << payload << " " << map;
                        dest = dest->append(temp);
                        if (mode) {
                            temp = new String("fmtp:");
                            *temp << payload << " mode=" << mode;
                            dest = dest->append(temp);
                        }
                        if (*s == "g729") {
                            temp = new String("fmtp:");
                            *temp << payload << " annexb=" <<
                                  ((0 != l->find("g729b")) ? "yes" : "no");
                            dest = dest->append(temp);
                        }
                        else if (*s == "amr") {
                            temp = new String("fmtp:");
                            *temp << payload << " octet-align=0";
                            dest = dest->append(temp);
                        }
                        else if (*s == "amr-o") {
                            temp = new String("fmtp:");
                            *temp << payload << " octet-align=1";
                            dest = dest->append(temp);
                        }
                    }
                }
            }
        }