C++程序  |  1670行  |  57.08 KB

/* ------------------------------------------------------------------
 * Copyright (C) 1998-2009 PacketVideo
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 * -------------------------------------------------------------------
 */

#include "session_info_parser.h"
#include "oscl_string_utils.h"
#include "rtsp_time_formats.h"
#include "sdp_info.h"
#include "oscl_str_ptr_len.h"
#include "rtsp_range_utils.h"
#include "oscl_string_containers.h"


SDP_ERROR_CODE parseSDPSessionInfo(const char *sdp_text, int length, SDPInfo *sdp)
{

    sessionDescription *session = sdp->getSessionInfo();

    bool o_field_found =  false;
    bool s_field_found = false;

    bool a_control_found = false;
    bool a_range_found = false;
    bool t_field_found = false;
    bool u_field_found = false;

    const char *end = sdp_text + length;

    const char *current_start = sdp_text;
    const char *line_start_ptr, *line_end_ptr;

    OsclMemoryFragment memFrag;

    // setup the known attribute fields here
    StrPtrLen author("a=author:");
    StrPtrLen version("a=version:");
    StrPtrLen copyright("a=copyright:");
    StrPtrLen rating("a=rating:");
    StrPtrLen range("a=range:");
    StrPtrLen wmf_version("a=X-wmfversion:");
    StrPtrLen allowrecord("a=X-allowrecord");
    StrPtrLen random_access("a=random_access_denied");
    StrPtrLen control("a=control:");
    StrPtrLen creation_date("a=creation_date:");
    StrPtrLen video_only_allowed_true("a=video_only_allowed:true");
    StrPtrLen video_only_allowed_false("a=video_only_allowed:false");

    StrPtrLen etag("a=etag:");
    //StrPtrLen security("a=X-security_flag:");
    StrPtrLen random_filler("a=X-random_filler:");
    StrPtrLen digital_signature("a=X-digital_signature:");
    StrPtrLen end_of_clip("a=X-end_of_clip:");
    StrPtrLen launch_URL("a=X-launch_URL:");
    StrPtrLen app_specific_string("a=X-app_specific_string:");
    StrPtrLen pause_denied("a=X-pause_denied");

    StrPtrLen qoe_metrics("a=3GPP-QoE-Metrics:");
    StrPtrLen sdp_int_key("a=3GPP-Integrity-Key:");
    StrPtrLen sdp_auth("a=3GPP-SDP-Auth:");
    StrPtrLen alt_gp("a=alt-group:");
    StrPtrLen asset_info("a=3GPP-Asset-Information:");

    // added for RM

    StrPtrLen sdpplinversion("a=SdpplinVersion:");
    StrPtrLen flags("a=Flags:");
    StrPtrLen isrealdatatype("a=IsRealDataType:");
    StrPtrLen streamcount("a=StreamCount:");
    StrPtrLen title("a=Title:");
    StrPtrLen keywords("a=Keywords:");
    StrPtrLen abstract("a=Abstract:");
    StrPtrLen ASMrulebook("a=ASMRuleBook");



    while (get_next_line(current_start, end,
                         line_start_ptr, line_end_ptr))
    {
        // check for line type
        switch (*line_start_ptr)
        {
            case 'v':
            {
                uint32 version;
                if (*(line_start_ptr + 1) != '=')
                {
                    return SDP_BAD_SESSION_FORMAT;
                }
                if (PV_atoi(line_start_ptr + 2, 'd', line_end_ptr - line_start_ptr - 2, version) == false)
                {
                    return SDP_BAD_SESSION_FORMAT;
                }

                if (version)
                    return SDP_BAD_SESSION_FORMAT;
                session->setProtocolVersion(version);

                break;
            }

            case 'o':
            {
                if (*(line_start_ptr + 1) != '=')
                {
                    return SDP_BAD_SESSION_FORMAT;
                }

                o_field_found = true;
                // parse through each field
                const char *sptr, *eptr;
                sptr = skip_whitespace(line_start_ptr + 2, line_end_ptr);
                if (sptr >= line_end_ptr)
                {
                    return SDP_BAD_SESSION_FORMAT;
                }

                eptr = skip_to_whitespace(sptr, line_end_ptr);
                if (eptr <= sptr)
                {
                    return SDP_BAD_SESSION_FORMAT;
                }

                // get the username
                memFrag.ptr = (void*)sptr;
                memFrag.len = (eptr - sptr);
                session->setOUsername(memFrag);

                // get the sessionID
                sptr = skip_whitespace(eptr, line_end_ptr);
                //o=- -1586996066 -1586996066 IN IP4 172.31.105.21
                //workaround for server found during IOT. 12/12/06
                while ((*sptr < '0') || (*sptr > '9'))
                {
                    sptr++;
                    if (sptr >= line_end_ptr)
                    {
                        return SDP_BAD_SESSION_FORMAT;
                    }
                }

                eptr = skip_to_whitespace(sptr, line_end_ptr);
                if (eptr <= sptr)
                {
                    return SDP_BAD_SESSION_FORMAT;
                }

                uint64 sessionId64;
                if (!PV_atoi(sptr, 'd', eptr - sptr, sessionId64)) // session ID should be numeric
                    return SDP_BAD_SESSION_FORMAT;

                uint32 sessionId =
                    Oscl_Int64_Utils::get_uint64_lower32(sessionId64);
                session->setOSessionID(sessionId);

                // get the version
                sptr = skip_whitespace(eptr, line_end_ptr);
                //o=- -1586996066 -1586996066 IN IP4 172.31.105.21
                //workaround for server found during IOT. 12/12/06
                while ((*sptr < '0') || (*sptr > '9'))
                {
                    sptr++;
                    if (sptr >= line_end_ptr)
                    {
                        return SDP_BAD_SESSION_FORMAT;
                    }
                }

                eptr = skip_to_whitespace(sptr, line_end_ptr);
                if (eptr <= sptr)
                {
                    return SDP_BAD_SESSION_FORMAT;
                }

                uint64 version64;
                if (!PV_atoi(sptr, 'd', eptr - sptr, version64))
                    return SDP_BAD_SESSION_FORMAT;

                uint32 version =
                    Oscl_Int64_Utils::get_uint64_lower32(version64);
                session->setOVersion(version);

                // get the network type
                sptr = skip_whitespace(eptr, line_end_ptr);
                if (sptr >= line_end_ptr)
                {
                    return SDP_BAD_SESSION_FORMAT;
                }

                eptr = skip_to_whitespace(sptr, line_end_ptr);
                if (eptr <= sptr)
                {
                    return SDP_BAD_SESSION_FORMAT;
                }
                memFrag.ptr = (void*)sptr;
                memFrag.len = (eptr - sptr);
                session->setONetworkType(memFrag);

                // get the address type
                sptr = skip_whitespace(eptr, line_end_ptr);
                if (sptr >= line_end_ptr)
                {
                    return SDP_BAD_SESSION_FORMAT;
                }

                eptr = skip_to_whitespace(sptr, line_end_ptr);
                if (eptr <= sptr)
                {
                    return SDP_BAD_SESSION_FORMAT;
                }
                memFrag.ptr = (void*)sptr;
                memFrag.len = (eptr - sptr);
                session->setOAddressType(memFrag);


                // get the orginator address
                sptr = skip_whitespace(eptr, line_end_ptr);
                if (sptr >= line_end_ptr)
                {
                    return SDP_BAD_SESSION_FORMAT;
                }

                eptr = skip_to_whitespace(sptr, line_end_ptr);
                if (eptr <= sptr)
                {
                    return SDP_BAD_SESSION_FORMAT;
                }
                memFrag.ptr = (void*)sptr;
                memFrag.len = (eptr - sptr);
                session->setOAddress(memFrag);


                break;
            }

            case 's':
            {
                // the session Name is a string which can contain whitespace

                if (s_field_found) // only one s field allowed at session level
                    return SDP_BAD_SESSION_FORMAT;

                if (*(line_start_ptr + 1) != '=')
                {
                    return SDP_BAD_SESSION_FORMAT;
                }

                s_field_found = true;

                // parse through each field
                const char *sptr, *eptr;

                sptr = skip_whitespace(line_start_ptr + 2, line_end_ptr);
                if (sptr >= line_end_ptr)
                {
                    break;
                    //          return SDP_BAD_SESSION_FORMAT;
                }

                eptr = skip_to_line_term(sptr, line_end_ptr);
                if (eptr <= sptr)
                {

                    return SDP_BAD_SESSION_FORMAT;
                }

                // get the session name
                memFrag.ptr = (void*)sptr;
                memFrag.len = (eptr - sptr);
                session->setSessionName(memFrag);

                break;
            }

            case 'u':
            {
                // the session Name is a string which can contain whitespace

                if (u_field_found) // only one s field allowed at session level
                    return SDP_BAD_SESSION_FORMAT;

                if (*(line_start_ptr + 1) != '=')
                {
                    return SDP_BAD_SESSION_FORMAT;
                }

                u_field_found = true;

                // parse through each field
                const char *sptr, *eptr;

                sptr = skip_whitespace(line_start_ptr + 2, line_end_ptr);
                if (sptr >= line_end_ptr)
                {
                    break;
                    //          return SDP_BAD_SESSION_FORMAT;
                }

                eptr = skip_to_line_term(sptr, line_end_ptr);
                if (eptr <= sptr)
                {

                    return SDP_BAD_SESSION_FORMAT;
                }

                // get the session name
                memFrag.ptr = (void*)sptr;
                memFrag.len = (eptr - sptr);
                session->setSessionURI(memFrag);

                break;
            }

            case 'i':
            {
                // the session info is a string which can contain whitespace
                if (*(line_start_ptr + 1) != '=')
                {
                    return SDP_BAD_SESSION_FORMAT;
                }

                // parse through each field
                const char *sptr, *eptr;

                sptr = skip_whitespace(line_start_ptr + 2, line_end_ptr);
                if (sptr >= line_end_ptr)
                {
                    break;
                    //          return SDP_BAD_SESSION_FORMAT;
                }

                eptr = skip_to_line_term(sptr, line_end_ptr);
                if (eptr <= sptr)
                {
                    return SDP_BAD_SESSION_FORMAT;
                }

                // get the session name
                memFrag.ptr = (void*)sptr;
                memFrag.len = (eptr - sptr);
                session->setSessionInformation(memFrag);


                break;
            }

            case 'c':
            {
                if (*(line_start_ptr + 1) != '=')
                {
                    return SDP_BAD_SESSION_FORMAT;
                }

                session->setCFieldStatus(true);
                // parse through each field
                const char *sptr, *eptr;

                // get the connection network type
                sptr = skip_whitespace(line_start_ptr + 2, line_end_ptr);
                if (sptr >= line_end_ptr)
                {
                    return SDP_BAD_SESSION_FORMAT;
                }

                eptr = skip_to_whitespace(sptr, line_end_ptr);
                if (eptr <= sptr)
                {
                    return SDP_BAD_SESSION_FORMAT;
                }

                memFrag.ptr = (void*)sptr;
                memFrag.len = (eptr - sptr);
                session->setCNetworkType(memFrag);


                // get the address type
                sptr = skip_whitespace(eptr, line_end_ptr);
                if (sptr >= line_end_ptr)
                {
                    return SDP_BAD_SESSION_FORMAT;
                }

                eptr = skip_to_whitespace(sptr, line_end_ptr);
                if (eptr <= sptr)
                {
                    return SDP_BAD_SESSION_FORMAT;
                }
                memFrag.ptr = (void*)sptr;
                memFrag.len = (eptr - sptr);
                session->setCAddressType(memFrag);
                uint32 len = OSCL_MIN((uint32)(eptr - sptr), oscl_strlen("IP6"));
                if (oscl_strncmp(sptr, "IP6", len) == 0)
                {
                    //TBD
                    break;
                }


                // get the address
                sptr = skip_whitespace(eptr, line_end_ptr);
                if (sptr >= line_end_ptr)
                {
                    return SDP_BAD_SESSION_FORMAT;
                }

                eptr = skip_to_whitespace(sptr, line_end_ptr);
                if (eptr < sptr)
                {
                    return SDP_BAD_SESSION_FORMAT;
                }
                memFrag.ptr = (void*)sptr;
                memFrag.len = (eptr - sptr);
                session->setCAddress(memFrag);
                uint32 address;
                const char *addrend = sptr;
                for (; *addrend != '.'; ++addrend);

                PV_atoi(sptr, 'd', addrend - sptr, address);

                if (address >= 224 && address <= 239) //multicast address look for TTL
                {
                    for (; (*sptr != '/') && (sptr < eptr); ++sptr);
                    if (sptr == eptr)
                        return SDP_BAD_SESSION_FORMAT; // no TTL found in multicast address.
                    else
                    {
                        uint32 ttl;
                        sptr = sptr + 1;
                        if (!PV_atoi(sptr, 'd', eptr - sptr, ttl))
                            return SDP_BAD_SESSION_FORMAT;
                        if (!(ttl <= 255))
                            return SDP_BAD_SESSION_FORMAT; // ttl out of range.

                    }
                }
                else  // unicast address
                {
                    for (; (*sptr != '/') && (sptr < eptr); ++sptr);
                    if (!oscl_strncmp(sptr, "/", 1))
                        return SDP_BAD_SESSION_FORMAT; //unicast address can not have TTL.
                }

                if (eptr < line_end_ptr)
                    return SDP_BAD_SESSION_FORMAT;
                break;
            }

            case 't':
            {
                uint64 start_time, stop_time;
                if (*(line_start_ptr + 1) != '=')
                {
                    return SDP_BAD_SESSION_FORMAT;
                }

                t_field_found = true;

                const char *sptr, *eptr;
                sptr = skip_whitespace(line_start_ptr + 2, line_end_ptr);
                if (sptr >= line_end_ptr)
                {
                    return SDP_BAD_SESSION_FORMAT;
                }

                eptr = skip_to_whitespace(sptr, line_end_ptr);
                if (eptr <= sptr)
                {
                    return SDP_BAD_SESSION_FORMAT;
                }

                if (PV_atoi(sptr, 'd', (eptr - sptr), start_time) == false)
                {
                    return SDP_BAD_SESSION_FORMAT;
                }

                session->setSessionStartTime(start_time);

                sptr = skip_whitespace(eptr, line_end_ptr);
                if (sptr >= line_end_ptr)
                {
                    return SDP_BAD_SESSION_FORMAT;
                }

                eptr = skip_to_whitespace(sptr, line_end_ptr);
                if (eptr <= sptr)
                {
                    return SDP_BAD_SESSION_FORMAT;
                }

                if (PV_atoi(sptr, 'd', (eptr - sptr),  stop_time) == false)
                {
                    return SDP_BAD_SESSION_FORMAT;
                }

                session->setSessionStopTime(stop_time);


                memFrag.ptr = (void*)sptr;
                memFrag.len = (eptr - sptr);
                session->setExpiryDate(memFrag);
                break;
            }

            case 'r':
            {
                uint32 repeat_interval, active_duration;
                char convert_to_sec = NULL_TERM_CHAR;

                if (*(line_start_ptr + 1) != '=')
                {
                    return SDP_BAD_SESSION_FORMAT;
                }

                const char *sptr, *eptr;
                sptr = skip_whitespace(line_start_ptr + 2, line_end_ptr);
                if (sptr >= line_end_ptr)
                {
                    return SDP_BAD_SESSION_FORMAT;
                }

                eptr = skip_to_whitespace(sptr, line_end_ptr);
                if (eptr <= sptr)
                {
                    return SDP_BAD_SESSION_FORMAT;
                }

                int size = 0;
                if (!oscl_strncmp((eptr - 1), "d", 1) || !oscl_strncmp((eptr - 1), "h", 1) || !oscl_strncmp((eptr - 1), "m", 1) || !oscl_strncmp((eptr - 1), "s", 1))
                {
                    convert_to_sec = *(eptr - 1);
                    size = eptr - 1 - sptr;
                }
                else
                    size = eptr - sptr;


                if (PV_atoi(sptr, 'd', size, repeat_interval) == false)
                {
                    return SDP_BAD_SESSION_FORMAT;
                }

                if (convert_to_sec == 'd')
                {
                    repeat_interval = repeat_interval * 24 * 3600;
                    convert_to_sec = NULL_TERM_CHAR;
                }
                else if (convert_to_sec == 'h')
                {
                    repeat_interval = repeat_interval * 3600;
                    convert_to_sec = NULL_TERM_CHAR;
                }
                else if (convert_to_sec == 'm')
                {
                    repeat_interval = repeat_interval * 60;
                    convert_to_sec = NULL_TERM_CHAR;
                }
                else if (convert_to_sec == 's')
                {
                    convert_to_sec = NULL_TERM_CHAR; // already in seconds.
                }



                session->setRepeatInterval(repeat_interval);
                eptr = skip_whitespace(eptr, line_end_ptr);

                sptr = skip_whitespace(eptr, line_end_ptr);
                if (sptr >= line_end_ptr)
                {
                    return SDP_BAD_SESSION_FORMAT;
                }

                eptr = skip_to_whitespace(sptr, line_end_ptr);
                if (eptr <= sptr)
                {
                    return SDP_BAD_SESSION_FORMAT;
                }

                if (!oscl_strncmp((eptr - 1), "d", 1) || !oscl_strncmp((eptr - 1), "h", 1) || !oscl_strncmp((eptr - 1), "m", 1) || !oscl_strncmp((eptr - 1), "s", 1))
                {
                    convert_to_sec = *(eptr - 1);
                    size = eptr - 1 - sptr;
                }
                else
                    size = eptr - sptr;

                if (PV_atoi(sptr, 'd', size,  active_duration) == false)
                {
                    return SDP_BAD_SESSION_FORMAT;
                }

                if (convert_to_sec == 'd')
                {
                    active_duration = active_duration * 24 * 3600;
                    convert_to_sec = NULL_TERM_CHAR;
                }
                else if (convert_to_sec == 'h')
                {
                    active_duration = active_duration * 3600;
                    convert_to_sec = NULL_TERM_CHAR;
                }
                else if (convert_to_sec == 'm')
                {
                    active_duration = active_duration * 60;
                    convert_to_sec = NULL_TERM_CHAR;
                }
                else if (convert_to_sec == 's')
                {
                    convert_to_sec = NULL_TERM_CHAR;
                }

                session->setActiveDuration(active_duration);

                while (sptr < line_end_ptr)
                {
                    uint32 offset;

                    sptr = skip_whitespace(eptr, line_end_ptr);
                    if (sptr >= line_end_ptr)
                    {
                        return SDP_BAD_SESSION_FORMAT;
                    }

                    eptr = skip_to_whitespace(sptr, line_end_ptr);
                    if (eptr <= sptr)
                    {
                        return SDP_BAD_SESSION_FORMAT;
                    }

                    if (!oscl_strncmp((eptr - 1), "d", 1) || !oscl_strncmp((eptr - 1), "h", 1) || !oscl_strncmp((eptr - 1), "m", 1) || !oscl_strncmp((eptr - 1), "s", 1))
                    {
                        size = eptr - 1 - sptr;
                        convert_to_sec = *(eptr - 1);
                    }
                    else
                        size = eptr - sptr;

                    if (PV_atoi(sptr, 'd', size,  offset) == false)
                    {
                        return SDP_BAD_SESSION_FORMAT;
                    }

                    if (convert_to_sec == 'd')
                    {
                        offset = offset * 24 * 3600;
                        convert_to_sec = NULL_TERM_CHAR;
                    }
                    else if (convert_to_sec == 'h')
                    {
                        offset = offset * 3600;
                        convert_to_sec = NULL_TERM_CHAR;
                    }
                    else if (convert_to_sec == 'm')
                    {
                        offset = offset * 60;
                        convert_to_sec = NULL_TERM_CHAR;
                    }
                    else if (convert_to_sec == 's')
                    {
                        convert_to_sec = NULL_TERM_CHAR;
                    }

                    session->addOffset(offset);

                    sptr = eptr;
                }
                break;
            }

            case 'b':
            {
                if (!oscl_strncmp(line_start_ptr, "b=AS:", oscl_strlen("b=AS:")))
                {
                    const char *sptr;
                    sptr = line_start_ptr + oscl_strlen("b=AS:");
                    sptr = skip_whitespace(sptr, line_end_ptr);
                    if (sptr >= line_end_ptr)
                    {
                        return SDP_BAD_SESSION_FORMAT;
                    }

                    uint32 bitRate;
                    if (PV_atoi(sptr, 'd', (line_end_ptr - sptr),  bitRate) == true)
                    {
                        session->setBitrate(1000*bitRate);
                    }
                    else
                    {
                        return SDP_BAD_SESSION_FORMAT;
                    }
                }
                else if (!oscl_strncmp(line_start_ptr, "b=RS:", oscl_strlen("b=RS:")))
                {
                    const char *sptr;
                    sptr = line_start_ptr + oscl_strlen("b=AS:");
                    sptr = skip_whitespace(sptr, line_end_ptr);
                    if (sptr >= line_end_ptr)
                    {
                        return SDP_BAD_SESSION_FORMAT;
                    }

                    uint32 rtcpBWSender;
                    if (PV_atoi(sptr, 'd', (line_end_ptr - sptr),  rtcpBWSender) == true)
                    {
                        session->setRTCPSenderBitRate(rtcpBWSender);
                    }
                    else
                    {
                        return SDP_BAD_SESSION_FORMAT;
                    }
                }
                else if (!oscl_strncmp(line_start_ptr, "b=RR:", oscl_strlen("b=RR:")))
                {
                    const char *sptr;
                    sptr = line_start_ptr + oscl_strlen("b=AS:");
                    sptr = skip_whitespace(sptr, line_end_ptr);
                    if (sptr >= line_end_ptr)
                    {
                        return SDP_BAD_SESSION_FORMAT;
                    }

                    uint32 rtcpBWReceiver;
                    if (PV_atoi(sptr, 'd', (line_end_ptr - sptr),  rtcpBWReceiver) == true)
                    {
                        session->setRTCPReceiverBitRate(rtcpBWReceiver);
                    }
                    else
                    {
                        return SDP_BAD_SESSION_FORMAT;
                    }
                }
                else if (!oscl_strncmp(line_start_ptr, "b=TIAS:", oscl_strlen("b=TIAS:")))
                {
                    const char *sptr;
                    sptr = line_start_ptr + oscl_strlen("b=TIAS:");
                    sptr = skip_whitespace(sptr, line_end_ptr);
                    if (sptr >= line_end_ptr)
                    {
                        return SDP_BAD_SESSION_FORMAT;
                    }

                    uint32 bMod;
                    if (PV_atoi(sptr, 'd', (line_end_ptr - sptr),  bMod) == true)
                    {
                        session->setBWtias(1000 * bMod);
                    }
                    else
                    {
                        return SDP_BAD_SESSION_FORMAT;
                    }
                }
                break;
            }

            case 'k':
            {
                const char *sptr, *eptr;
                if (!oscl_strncmp(line_start_ptr, "k=clear:", oscl_strlen("k=clear:")))
                {
                    sptr = line_start_ptr + oscl_strlen("k=clear:");
                    sptr = skip_whitespace(sptr, line_end_ptr);
                    if (sptr >= line_end_ptr)
                    {
                        return SDP_BAD_SESSION_FORMAT;
                    }

                    eptr = skip_to_line_term(sptr, line_end_ptr);
                    if (eptr <= sptr)
                    {
                        return SDP_BAD_SESSION_FORMAT;
                    }

                    memFrag.ptr = (void*)sptr;
                    memFrag.len = (eptr - sptr);
                    session->setEncryptionKey(memFrag);
                }
                else if (!oscl_strncmp(line_start_ptr, "k=base64:", oscl_strlen("k=base64:")))
                {

                    sptr = line_start_ptr + oscl_strlen("k=base64:");
                    sptr = skip_whitespace(sptr, line_end_ptr);
                    if (sptr >= line_end_ptr)
                    {
                        return SDP_BAD_SESSION_FORMAT;
                    }

                    eptr = skip_to_line_term(sptr, line_end_ptr);
                    if (eptr <= sptr)
                    {
                        return SDP_BAD_SESSION_FORMAT;
                    }

                    memFrag.ptr = (void*)sptr;
                    memFrag.len = (eptr - sptr);
                    session->setEncryptionKey(memFrag);
                }
                else if (!oscl_strncmp(line_start_ptr, "k=uri:", oscl_strlen("k=uri:")))
                {

                    sptr = line_start_ptr + oscl_strlen("k=uri:");
                    sptr = skip_whitespace(sptr, line_end_ptr);
                    if (sptr >= line_end_ptr)
                    {
                        return SDP_BAD_SESSION_FORMAT;
                    }

                    eptr = skip_to_line_term(sptr, line_end_ptr);
                    if (eptr <= sptr)
                    {
                        return SDP_BAD_SESSION_FORMAT;
                    }

                    memFrag.ptr = (void*)sptr;
                    memFrag.len = (eptr - sptr);
                    session->setEncryptionKey(memFrag);
                }
                else
                {
                    sptr = line_start_ptr;
                    eptr = skip_to_line_term(sptr, line_end_ptr);
                    if (eptr <= sptr)
                    {
                        return SDP_BAD_SESSION_FORMAT;
                    }
                }
                break;
            }

            case 'a':
            {

                // check to see if it is a known attribute -- otherwise ignore it.
                const char *sptr, *eptr;
                if (!oscl_strncmp(line_start_ptr, author.c_str(), author.length()))
                {
                    sptr = skip_whitespace(line_start_ptr + author.length(),
                                           line_end_ptr);
                    if (sptr >= line_end_ptr)
                    {
                        break;
                        //            return SDP_BAD_SESSION_FORMAT;
                    }

                    eptr = skip_to_line_term(sptr, line_end_ptr);
                    if (eptr <= sptr)
                    {
                        return SDP_BAD_SESSION_FORMAT;
                    }

                    memFrag.ptr = (void*)sptr;
                    memFrag.len = (eptr - sptr);
                    session->setAuthor(memFrag);

                }
                else if (!oscl_strncmp(line_start_ptr, version.c_str(),
                                       version.length()))
                {
                    sptr = skip_whitespace(line_start_ptr + version.length(),
                                           line_end_ptr);
                    if (sptr >= line_end_ptr)
                    {
                        break;
                        //            return SDP_BAD_SESSION_FORMAT;
                    }

                    eptr = skip_to_line_term(sptr, line_end_ptr);
                    if (eptr <= sptr)
                    {
                        return SDP_BAD_SESSION_FORMAT;
                    }

                    memFrag.ptr = (void*)sptr;
                    memFrag.len = (eptr - sptr);
                    session->setVersion(memFrag);


                }
                else if (!oscl_strncmp(line_start_ptr, copyright.c_str(),
                                       copyright.length()))
                {

                    sptr = skip_whitespace(line_start_ptr + copyright.length(),
                                           line_end_ptr);
                    if (sptr >= line_end_ptr)
                    {
                        break;
                        //            return SDP_BAD_SESSION_FORMAT;
                    }

                    eptr = skip_to_line_term(sptr, line_end_ptr);
                    if (eptr <= sptr)
                    {
                        return SDP_BAD_SESSION_FORMAT;
                    }

                    memFrag.ptr = (void*)sptr;
                    memFrag.len = (eptr - sptr);
                    session->setCopyright(memFrag);

                }
                else if (!oscl_strncmp(line_start_ptr, rating.c_str(), rating.length()))
                {

                    sptr = skip_whitespace(line_start_ptr + rating.length(),
                                           line_end_ptr);
                    if (sptr >= line_end_ptr)
                    {
                        break;
                        //            return SDP_BAD_SESSION_FORMAT;
                    }

                    eptr = skip_to_line_term(sptr, line_end_ptr);
                    if (eptr <= sptr)
                    {
                        return SDP_BAD_SESSION_FORMAT;
                    }
                    memFrag.ptr = (void*)sptr;
                    memFrag.len = (eptr - sptr);
                    session->setRating(memFrag);
                }
                else if (!oscl_strncmp(line_start_ptr, range.c_str(), range.length()))
                {
                    RtspRangeType rangeVal;
                    if (parseRtspRange((line_start_ptr + range.length()), (line_end_ptr - line_start_ptr - range.length()),
                                       rangeVal))
                    {
                        session->setRange(rangeVal);
                        a_range_found = true;
                    }
                }
                else if (!oscl_strncmp(line_start_ptr, wmf_version.c_str(),
                                       wmf_version.length()))
                {

                    sptr = skip_whitespace(line_start_ptr + wmf_version.length(),
                                           line_end_ptr);
                    if (sptr >= line_end_ptr)
                    {
                        break;
                        //            return SDP_BAD_SESSION_FORMAT;
                    }

                    eptr = skip_to_line_term(sptr, line_end_ptr);
                    if (eptr <= sptr)
                    {
                        return SDP_BAD_SESSION_FORMAT;
                    }

                    memFrag.ptr = (void*)sptr;
                    memFrag.len = (eptr - sptr);
                    session->setWmfVersion(memFrag);
                }
                else if (!oscl_strncmp(line_start_ptr, allowrecord.c_str(),
                                       allowrecord.length()))
                {
                    session->setAllowRecord(true);
                }
                else if (!oscl_strncmp(line_start_ptr, random_access.c_str(),
                                       random_access.length()))
                {
                    session->setRandomAccessDenied(true);
                }

                else if (!oscl_strncmp(line_start_ptr, control.c_str(),
                                       control.length()))
                {

                    sptr = skip_whitespace(line_start_ptr + control.length(),
                                           line_end_ptr);
                    if (sptr >= line_end_ptr)
                    {
                        break;
                        //            return SDP_BAD_SESSION_FORMAT;
                    }

                    eptr = skip_to_line_term(sptr, line_end_ptr);
                    if (eptr <= sptr)
                    {
                        return SDP_BAD_SESSION_FORMAT;
                    }

                    OSCL_HeapString<SDPParserAlloc> control_str(sptr, eptr - sptr);
                    session->setControlURL(control_str);
                    a_control_found = true;

                }

                else if (!oscl_strncmp(line_start_ptr, creation_date.c_str(),
                                       creation_date.length()))
                {

                    sptr = skip_whitespace(line_start_ptr + creation_date.length(),
                                           line_end_ptr);
                    if (sptr >= line_end_ptr)
                    {

                        return SDP_BAD_SESSION_FORMAT;
                    }

                    eptr = skip_to_line_term(sptr, line_end_ptr);
                    if (eptr <= sptr)
                    {
                        return SDP_BAD_SESSION_FORMAT;
                    }

                    memFrag.ptr = (void*)sptr;
                    memFrag.len = (eptr - sptr);
                    session->setCreationDate(memFrag);
                }

                else if (!oscl_strncmp(line_start_ptr, video_only_allowed_true.c_str(),
                                       video_only_allowed_true.length()))
                {

                    session->setVideoOnlyAllowed(ALLOWED);
                }

                else if (!oscl_strncmp(line_start_ptr, video_only_allowed_false.c_str(),
                                       video_only_allowed_false.length()))
                {
                    session->setVideoOnlyAllowed(NOT_ALLOWED);
                }

                else if (!oscl_strncmp(line_start_ptr, etag.c_str(), etag.length()))
                {

                    sptr = skip_whitespace(line_start_ptr + etag.length(),
                                           line_end_ptr);
                    if (sptr >= line_end_ptr)
                    {
                        break;
                    }

                    eptr = skip_to_line_term(sptr, line_end_ptr);
                    if (eptr <= sptr)
                    {
                        return SDP_BAD_SESSION_FORMAT;
                    }

                    memFrag.ptr = (void*)sptr;
                    memFrag.len = (eptr - sptr);
                    session->setETag(memFrag);
                }

                else if (!oscl_strncmp(line_start_ptr, random_filler.c_str(), random_filler.length()))
                {

                    sptr = skip_whitespace(line_start_ptr + random_filler.length(), line_end_ptr);

                    if (sptr >= line_end_ptr)
                    {
                        break;
                    }

                    eptr = skip_to_line_term(sptr, line_end_ptr);
                    if (eptr <= sptr)
                    {
                        return SDP_BAD_SESSION_FORMAT;
                    }

                    memFrag.ptr = (void*)sptr;
                    memFrag.len = (eptr - sptr);
                    session->setRandomFiller(memFrag);
                }

                else if (!oscl_strncmp(line_start_ptr, digital_signature.c_str(),
                                       digital_signature.length()))
                {

                    sptr = skip_whitespace(line_start_ptr + digital_signature.length(), line_end_ptr);

                    if (sptr >= line_end_ptr)
                    {
                        break;
                    }

                    eptr = skip_to_line_term(sptr, line_end_ptr);
                    if (eptr <= sptr)
                    {
                        return SDP_BAD_SESSION_FORMAT;
                    }

                    memFrag.ptr = (void*)sptr;
                    memFrag.len = (eptr - sptr);
                    session->setDigitalSignature(memFrag);
                }

                else if (!oscl_strncmp(line_start_ptr, launch_URL.c_str(), launch_URL.length()))
                {

                    sptr = skip_whitespace(line_start_ptr + launch_URL.length(), line_end_ptr);

                    if (sptr >= line_end_ptr)
                    {
                        break;
                    }

                    eptr = skip_to_line_term(sptr, line_end_ptr);
                    if (eptr <= sptr)
                    {
                        return SDP_BAD_SESSION_FORMAT;
                    }

                    memFrag.ptr = (void*)sptr;
                    memFrag.len = (eptr - sptr);
                    session->setLaunchURL(memFrag);
                }

                else if (!oscl_strncmp(line_start_ptr, end_of_clip.c_str(), end_of_clip.length()))
                {

                    sptr = skip_whitespace(line_start_ptr + end_of_clip.length(),
                                           line_end_ptr);

                    if (sptr >= line_end_ptr)
                    {
                        break;
                    }

                    eptr = skip_to_line_term(sptr, line_end_ptr);
                    if (eptr <= sptr)
                    {
                        return SDP_BAD_SESSION_FORMAT;
                    }
                    //uint32 action = 0;
                    StrPtrLen nothing("NOTHING");
                    StrPtrLen close("CLOSE");
                    StrPtrLen launch("LAUNCH");

                    if (!oscl_strncmp(nothing.c_str(), sptr, nothing.length()))
                    {
                        session->setEndOfClipAction(DEFAULT);
                    }
                    else if (!oscl_strncmp(close.c_str(), sptr, close.length()))
                    {
                        session->setEndOfClipAction(CLOSE_PLAYER);
                    }
                    else if (!oscl_strncmp(launch.c_str(), sptr, launch.length()))
                    {
                        session->setEndOfClipAction(LAUNCH_URL);
                    }
                }

                // added for RM
                else if (!oscl_strncmp(line_start_ptr, sdpplinversion.c_str(),
                                       sdpplinversion.length()))
                {
                    uint32 version;

                    sptr = skip_whitespace(line_start_ptr + sdpplinversion.length(), line_end_ptr);
                    if (sptr >= line_end_ptr)
                    {
                        return SDP_BAD_SESSION_FORMAT;
                    }

                    eptr = skip_to_whitespace(sptr, line_end_ptr);
                    if (eptr <= sptr)
                    {
                        return SDP_BAD_SESSION_FORMAT;
                    }

                    if (PV_atoi(sptr, 'd', (eptr - sptr), version) == false)
                    {
                        return SDP_BAD_SESSION_FORMAT;
                    }

                    session->setSdpplinVersion(version);

                }

                else if (!oscl_strncmp(line_start_ptr, flags.c_str(),
                                       flags.length()))
                {
                    uint32 flag;
                    sptr = skip_whitespace(line_start_ptr + flags.length(), line_end_ptr);
                    if (sptr >= line_end_ptr)
                    {
                        return SDP_BAD_SESSION_FORMAT;
                    }

                    eptr = skip_to_whitespace(sptr, line_end_ptr);
                    if (eptr <= sptr)
                    {
                        return SDP_BAD_SESSION_FORMAT;
                    }

                    for (; *sptr != ';'; sptr++);
                    sptr = sptr + 1;

                    if (PV_atoi(sptr, 'd', (eptr - sptr), flag) == false)
                    {
                        return SDP_BAD_SESSION_FORMAT;
                    }

                    session->setFlags(flag);

                }

                else if (!oscl_strncmp(line_start_ptr, streamcount.c_str(),
                                       streamcount.length()))
                {
                    uint32 count;

                    sptr = skip_whitespace(line_start_ptr + streamcount.length(), line_end_ptr);
                    if (sptr >= line_end_ptr)
                    {
                        return SDP_BAD_SESSION_FORMAT;
                    }

                    eptr = skip_to_whitespace(sptr, line_end_ptr);
                    if (eptr <= sptr)
                    {
                        return SDP_BAD_SESSION_FORMAT;
                    }

                    for (; *sptr != ';'; sptr++);
                    sptr = sptr + 1;

                    if (PV_atoi(sptr, 'd', (eptr - sptr), count) == false)
                    {
                        return SDP_BAD_SESSION_FORMAT;
                    }

                    session->setStreamCount(count);

                }

                else if (!oscl_strncmp(line_start_ptr, isrealdatatype.c_str(),
                                       isrealdatatype.length()))
                {
                    uint32 isrealdata;

                    sptr = skip_whitespace(line_start_ptr + isrealdatatype.length(), line_end_ptr);
                    if (sptr >= line_end_ptr)
                    {
                        return SDP_BAD_SESSION_FORMAT;
                    }

                    eptr = skip_to_whitespace(sptr, line_end_ptr);
                    if (eptr <= sptr)
                    {
                        return SDP_BAD_SESSION_FORMAT;
                    }

                    for (; *sptr != ';'; sptr++);
                    sptr = sptr + 1;

                    if (PV_atoi(sptr, 'd', (eptr - sptr), isrealdata) == false)
                    {
                        return SDP_BAD_SESSION_FORMAT;
                    }

                    session->setIsRealDataType(isrealdata);
                }
                else if (!oscl_strncmp(line_start_ptr, "a=Author:", author.length()))
                {
                    sptr = skip_whitespace(line_start_ptr + author.length(),
                                           line_end_ptr);
                    if (sptr >= line_end_ptr)
                    {
                        break;
                        //            return SDP_BAD_SESSION_FORMAT;
                    }

                    eptr = skip_to_line_term(sptr, line_end_ptr);
                    if (eptr <= sptr)
                    {
                        return SDP_BAD_SESSION_FORMAT;
                    }

                    for (; *sptr != ';'; sptr++);
                    sptr = sptr + 1;

                    memFrag.ptr = (void*)sptr;
                    memFrag.len = (eptr - sptr);
                    session->setAuthor(memFrag);

                }
                else if (!oscl_strncmp(line_start_ptr, "a=Copyright:", copyright.length()))
                {
                    sptr = skip_whitespace(line_start_ptr + copyright.length(),
                                           line_end_ptr);
                    if (sptr >= line_end_ptr)
                    {
                        break;
                        //            return SDP_BAD_SESSION_FORMAT;
                    }

                    eptr = skip_to_line_term(sptr, line_end_ptr);
                    if (eptr <= sptr)
                    {
                        return SDP_BAD_SESSION_FORMAT;
                    }

                    for (; *sptr != ';'; sptr++);
                    sptr = sptr + 1;

                    memFrag.ptr = (void*)sptr;
                    memFrag.len = (eptr - sptr);
                    session->setCopyright(memFrag);

                }
                else if (!oscl_strncmp(line_start_ptr, title.c_str(),
                                       title.length()))
                {

                    sptr = skip_whitespace(line_start_ptr + title.length(),
                                           line_end_ptr);
                    if (sptr >= line_end_ptr)
                    {
                        break;
                        //            return SDP_BAD_SESSION_FORMAT;
                    }

                    eptr = skip_to_line_term(sptr, line_end_ptr);
                    if (eptr <= sptr)
                    {
                        return SDP_BAD_SESSION_FORMAT;
                    }

                    for (; *sptr != ';'; sptr++);
                    sptr = sptr + 1;

                    memFrag.ptr = (void*)(sptr + 1);
                    memFrag.len = ((eptr - 2) - sptr);
                    session->setTitle(memFrag);

                }

                else if (!oscl_strncmp(line_start_ptr, keywords.c_str(),
                                       keywords.length()))
                {

                    sptr = skip_whitespace(line_start_ptr + keywords.length(),
                                           line_end_ptr);
                    if (sptr >= line_end_ptr)
                    {
                        break;
                        //            return SDP_BAD_SESSION_FORMAT;
                    }

                    eptr = skip_to_line_term(sptr, line_end_ptr);
                    if (eptr <= sptr)
                    {
                        return SDP_BAD_SESSION_FORMAT;
                    }

                    for (; *sptr != ';'; sptr++);
                    sptr = sptr + 1;

                    memFrag.ptr = (void*)(sptr + 1);
                    memFrag.len = ((eptr - 2) - sptr);
                    session->setKeywords(memFrag);

                }

                else if (!oscl_strncmp(line_start_ptr, abstract.c_str(),
                                       abstract.length()))
                {

                    sptr = skip_whitespace(line_start_ptr + abstract.length(),
                                           line_end_ptr);
                    if (sptr >= line_end_ptr)
                    {
                        break;
                        //            return SDP_BAD_SESSION_FORMAT;
                    }

                    eptr = skip_to_line_term(sptr, line_end_ptr);
                    if (eptr <= sptr)
                    {
                        return SDP_BAD_SESSION_FORMAT;
                    }

                    for (; *sptr != ';'; sptr++);
                    sptr = sptr + 1;

                    memFrag.ptr = (void*)(sptr + 1);
                    memFrag.len = ((eptr - 2) - sptr);
                    session->setAbstract(memFrag);

                }

                else if (!oscl_strncmp(line_start_ptr, ASMrulebook.c_str(),
                                       ASMrulebook.length()))
                {

                    sptr = skip_whitespace(line_start_ptr + ASMrulebook.length(),
                                           line_end_ptr);
                    if (sptr >= line_end_ptr)
                    {
                        break;
                        //            return SDP_BAD_SESSION_FORMAT;
                    }

                    eptr = skip_to_line_term(sptr, line_end_ptr);
                    if (eptr <= sptr)
                    {
                        return SDP_BAD_SESSION_FORMAT;
                    }

                    for (; *sptr != ';'; sptr++);
                    sptr = sptr + 1;

                    memFrag.ptr = (void*)sptr;
                    memFrag.len = (eptr - sptr);
                    session->setASMRuleBook(memFrag);

                }
                else if (!oscl_strncmp(line_start_ptr, app_specific_string.c_str(), app_specific_string.length()))
                {

                    sptr = skip_whitespace(line_start_ptr + app_specific_string.length(), line_end_ptr);

                    if (sptr >= line_end_ptr)
                    {
                        break;
                    }

                    eptr = skip_to_line_term(sptr, line_end_ptr);
                    if (eptr <= sptr)
                    {
                        return SDP_BAD_SESSION_FORMAT;
                    }

                    memFrag.ptr = (void*)sptr;
                    memFrag.len = (eptr - sptr);
                    session->setAppSpecificString(memFrag);
                }

                else if (!oscl_strncmp(line_start_ptr, pause_denied.c_str(),
                                       pause_denied.length()))
                {
                    session->setPauseDenied(true);
                }
                else if (!oscl_strncmp(line_start_ptr, qoe_metrics.c_str(),
                                       qoe_metrics.length()))
                {
                    const char *sptr;
                    sptr = line_start_ptr + qoe_metrics.length();
                    QoEMetricsType qMetrics;
                    oscl_memset(qMetrics.name, 0, 7);
                    qMetrics.rateFmt = QoEMetricsType::VAL;
                    qMetrics.rateVal = 0;
                    qMetrics.paramFmt = QoEMetricsType::IDIGIT;
                    qMetrics.paramExtIdigit = 0;
                    if (!parseQoEMetrics(sptr, line_end_ptr, qMetrics))
                        return SDP_BAD_SESSION_FORMAT;

                    session->setQoEMetrics(qMetrics);

                }
                else if (!oscl_strncmp(line_start_ptr, sdp_int_key.c_str(),
                                       sdp_int_key.length()))
                {
                    const char *sptr = line_start_ptr + sdp_int_key.length();
                    const char *eptr = sptr;
                    bool found_OMADRMv2_keyMethod = false;


                    sptr = skip_whitespace(sptr, line_end_ptr);
                    if (sptr > line_end_ptr)
                        return SDP_BAD_SESSION_FORMAT;


                    if (oscl_strncmp(sptr, "OMADRMv2:", oscl_strlen("OMADRMv2:")))
                    {

                        for (; *eptr != ':' ; ++eptr);
                        session->setKeyMethod(sptr, eptr - sptr);

                    }
                    else
                    {
                        found_OMADRMv2_keyMethod = true;
                        eptr = sptr + oscl_strlen("OMADRMv2:");
                        session->setKeyMethod(sptr, eptr - sptr);
                    }

                    sptr = eptr ;

                    sptr = skip_whitespace(sptr, line_end_ptr);

                    if (sptr > line_end_ptr)
                        return SDP_BAD_SESSION_FORMAT;
                    else if (sptr == line_end_ptr)
                        break;


                    if (!found_OMADRMv2_keyMethod)
                    {

                        session->setKeyData(sptr, line_end_ptr - sptr);
                        break;
                    }

                    eptr = sptr;
                    for (; *eptr != ','; ++eptr);

                    session->setKeyData(sptr, (eptr - sptr));

                    sptr = eptr + 1;

                    if (sptr > line_end_ptr)
                        return SDP_BAD_SESSION_FORMAT;

                    if (oscl_strncmp(sptr, "\"", 1))
                        return SDP_BAD_SESSION_FORMAT;
                    else
                        sptr = sptr + 1;

                    if (sptr > line_end_ptr)
                        return SDP_BAD_SESSION_FORMAT;

                    eptr = sptr;

                    for (; *eptr != '\"'; ++eptr);

                    session->setKeyContentIdURI(sptr , (eptr  - sptr));

                    sptr = eptr + 1;

                    if (sptr > line_end_ptr)
                        return SDP_BAD_SESSION_FORMAT;
                    if (oscl_strncmp(sptr, ",", 1))
                        return SDP_BAD_SESSION_FORMAT;

                    sptr = sptr + 1;

                    if (oscl_strncmp(sptr, "\"", 1))
                        return SDP_BAD_SESSION_FORMAT;
                    else
                        sptr = sptr + 1;

                    if (sptr > line_end_ptr)
                        return SDP_BAD_SESSION_FORMAT;

                    eptr = sptr;

                    for (; *eptr != '"'; ++eptr);

                    session->setKeyRightIssuerURI(sptr , ((eptr - 1) - sptr));

                    sptr = eptr + 1;
                    sptr = skip_whitespace(sptr, line_end_ptr);

                    if (sptr > line_end_ptr)
                        return SDP_BAD_SESSION_FORMAT;


                    session->setKeyFreshToken(sptr, (line_end_ptr - sptr));

                }
                else if (!oscl_strncmp(line_start_ptr, sdp_auth.c_str(),
                                       sdp_auth.length()))
                {
                    const char *sptr = line_start_ptr + sdp_auth.length();
                    memFrag.ptr = (void *)sptr;
                    memFrag.len = line_end_ptr - sptr;

                    session->setSdpAuthTag(memFrag);
                }
                else if (!oscl_strncmp(line_start_ptr, asset_info.c_str(),
                                       asset_info.length()))
                {
                    const char *sptr = line_start_ptr + asset_info.length();
                    AssetInfoType assetInfo;
                    if (!parseAssetInfo(sptr, line_end_ptr, assetInfo))
                        return SDP_BAD_SESSION_FORMAT;

                    session->setAssetInfo(assetInfo);

                }
                else if (!oscl_strncmp(line_start_ptr, alt_gp.c_str(),
                                       alt_gp.length()))
                {
                    const char *sptr = line_start_ptr + alt_gp.length();
                    sptr = skip_whitespace(sptr, line_end_ptr);

                    if (!oscl_strncmp(sptr, "BW", oscl_strlen("BW")))
                        session->setAltGroupBW(sptr, line_end_ptr - sptr);
                    else if (!oscl_strncmp(sptr, "LANG", oscl_strlen("LANG")))
                        session->setAltGroupLANG(sptr, line_end_ptr - sptr);
                    else
                        return SDP_BAD_SESSION_FORMAT;

                }
                if (!oscl_strncmp(line_start_ptr, "a=maxprate:", oscl_strlen("a=maxprate:")))
                {
                    line_start_ptr += oscl_strlen("a=maxprate:");
                    OsclFloat rate;
                    if (!PV_atof(line_start_ptr, line_end_ptr - line_start_ptr, rate))
                        return SDP_BAD_SESSION_FORMAT;
                    session->setMaxprate(rate);
                }

                break;
            }
            case 'e':
            {
                if (*(line_start_ptr + 1) != '=')
                {
                    return SDP_BAD_SESSION_FORMAT;
                }

                const char *sptr, *eptr;

                sptr = skip_whitespace(line_start_ptr + 2, line_end_ptr);
                if (sptr >= line_end_ptr)
                {
                    break;
                }

                eptr = skip_to_line_term(sptr, line_end_ptr);
                if (eptr <= sptr)
                {
                    return SDP_BAD_SESSION_FORMAT;
                }

                memFrag.ptr = (void*)sptr;
                memFrag.len = (eptr - sptr);
                session->setEmail(memFrag);
                break;
            }
            case 'p':
            {
                if (*(line_start_ptr + 1) != '=')
                {
                    return SDP_BAD_SESSION_FORMAT;
                }

                const char *sptr, *eptr;

                sptr = skip_whitespace(line_start_ptr + 2, line_end_ptr);
                if (sptr >= line_end_ptr)
                {
                    break;
                }

                eptr = skip_to_line_term(sptr, line_end_ptr);
                if (eptr <= sptr)
                {
                    return SDP_BAD_SESSION_FORMAT;
                }

                memFrag.ptr = (void*)sptr;
                memFrag.len = (eptr - sptr);
                session->setPhoneNumber(memFrag);
                break;
            }
        }
        current_start = line_end_ptr;
    }

    return SDP_SUCCESS;
}