Home | History | Annotate | Download | only in src
      1 /* ------------------------------------------------------------------
      2  * Copyright (C) 1998-2009 PacketVideo
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
     13  * express or implied.
     14  * See the License for the specific language governing permissions
     15  * and limitations under the License.
     16  * -------------------------------------------------------------------
     17  */
     18 #include "base_media_info_parser.h"
     19 #include "oscl_string_utils.h"
     20 #include "oscl_string_containers.h"
     21 #include "rtsp_range_utils.h"
     22 
     23 
     24 /* Function to allocate temporary buffer, OSCL_TRY() put here to avoid     */
     25 /* compiler warnings                                                       */
     26 static void newTmpBuf(uint32 len, char** buf)
     27 {
     28     int32 err;
     29     *buf = NULL;
     30 
     31     OSCL_TRY(err, *buf = OSCL_ARRAY_NEW(char, len));
     32 
     33     if (err != OsclErrNone)
     34     {
     35         *buf = NULL;
     36     }
     37 }
     38 
     39 SDP_ERROR_CODE
     40 SDPBaseMediaInfoParser::baseMediaInfoParser(const char* buff,
     41         mediaInfo* mediaStr,
     42         const int index,
     43         const int alt_id,
     44         bool alt_def_id,
     45         bool isSipSdp)
     46 {
     47     const char *current_start = buff; //Pointer to the beginning of the media text
     48     const char *end = buff + index;   //Pointer to the end of the media text
     49     const char *line_start_ptr, *line_end_ptr;
     50 
     51 
     52     bool a_range_found = false;
     53 
     54     bool a_rtpmap_found = false;
     55     bool a_control_found = false;
     56     bool a_control_set = false;
     57 
     58     OsclMemoryFragment memFrag;
     59 
     60     while (get_next_line(current_start, end,
     61                          line_start_ptr, line_end_ptr))
     62     {
     63         if ((!alt_def_id && !alt_id) || (alt_def_id) ||
     64                 ((!alt_def_id) && !oscl_strncmp(line_start_ptr, "a=alt:", oscl_strlen("a=alt:"))))
     65         {
     66             if (!alt_def_id && !oscl_strncmp(line_start_ptr, "a=alt:", oscl_strlen("a=alt:")))
     67             {
     68                 line_start_ptr += oscl_strlen("a=alt:");
     69                 const char *end1 = line_start_ptr;
     70                 for (; *end1 != ':'; end1++);
     71                 uint32 id;
     72                 if (!PV_atoi(line_start_ptr, 'd' , end1 - line_start_ptr, id))
     73                     return SDP_BAD_MEDIA_ALT_ID;
     74                 if ((int)id != alt_id)
     75                 {
     76                     //check if id is already present
     77                     Oscl_Vector<int, SDPParserAlloc> alt_track = mediaStr->getalternateTrackId();
     78                     bool found = false;
     79 
     80                     for (int ss = 0; ss < (int)alt_track.size(); ss++)
     81                     {
     82                         if (alt_track[ss] == (int)id)
     83                             found = true;
     84                     }
     85 
     86                     if (!found)
     87                         mediaStr->setalternateTrackId(id);
     88 
     89                     current_start = line_end_ptr;
     90                     continue;
     91                 }
     92 
     93                 line_start_ptr = end1 + 1;
     94                 line_start_ptr = skip_whitespace(line_start_ptr, line_end_ptr);
     95 
     96             }
     97 
     98             switch (*line_start_ptr)
     99             {
    100                 case 'm':
    101                 {
    102                     if (*(line_start_ptr + 1) != '=')
    103                     {
    104                         PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad m= line format"));
    105                         return SDP_BAD_MEDIA_FORMAT;
    106                     }
    107 
    108                     // parse through each field
    109                     const char *sptr, *eptr;
    110 
    111                     //line_start_ptr+2 since we need to start looking beyond the '=' sign
    112 
    113                     //get the media type (audio, video, application)
    114                     sptr = skip_whitespace(line_start_ptr + 2, line_end_ptr);
    115                     if (sptr >= line_end_ptr)
    116                     {
    117                         PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad m= line format for media type"));
    118                         return SDP_BAD_MEDIA_FORMAT;
    119                     }
    120 
    121                     eptr = skip_to_whitespace(sptr, line_end_ptr);
    122                     if (eptr <= sptr)
    123                     {
    124                         PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad m= line format"));
    125                         return SDP_BAD_MEDIA_FORMAT;
    126                     }
    127 
    128                     memFrag.ptr = (void*)sptr;
    129                     memFrag.len = (eptr - sptr);
    130 
    131                     mediaStr->setType(memFrag);
    132 
    133                     //get the suggested port number
    134                     sptr = skip_whitespace(eptr, line_end_ptr);
    135                     if (sptr >= line_end_ptr)
    136                     {
    137                         PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad m= line format for suggested port"));
    138                         return SDP_BAD_MEDIA_FORMAT;
    139                     }
    140 
    141                     eptr = skip_to_whitespace(sptr, line_end_ptr);
    142                     if (eptr <= sptr)
    143                     {
    144                         PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad m= line format"));
    145                         return SDP_BAD_MEDIA_FORMAT;
    146                     }
    147 
    148                     uint32 suggestedPort;
    149 
    150                     OSCL_HeapString<SDPParserAlloc> restOfLine(sptr, eptr - sptr);
    151                     const char *slash = oscl_strstr(restOfLine.get_cstr(), "/");
    152                     if (slash)
    153                     {
    154                         if (PV_atoi(restOfLine.get_cstr(), 'd', (slash - restOfLine.get_cstr()), suggestedPort) == true)
    155                         {
    156                             mediaStr->setSuggestedPort(suggestedPort);
    157                             // There must be number of ports info after the slash
    158                             uint32 numOfPorts;
    159                             const char *ports = oscl_strstr(sptr, "/");
    160                             ports++;
    161                             if (ports == NULL)
    162                             {
    163                                 PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad m= line format for ports info"));
    164                                 return SDP_BAD_MEDIA_FORMAT;
    165                             }
    166                             if (PV_atoi(ports, 'd', (eptr - ports), numOfPorts) == true)
    167                             {
    168                                 mediaStr->setNumOfPorts(numOfPorts);
    169                             }
    170                             else
    171                             {
    172                                 PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad m= line format for ports info"));
    173                                 return SDP_BAD_MEDIA_FORMAT;
    174                             }
    175                         }
    176                         else
    177                         {
    178                             PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad m= line format for ports info"));
    179                             return SDP_BAD_MEDIA_FORMAT;
    180                         }
    181                     }
    182                     else
    183                     {
    184                         if (PV_atoi(sptr, 'd', (eptr - sptr), suggestedPort) == true)
    185                         {
    186                             mediaStr->setSuggestedPort(suggestedPort);
    187                         }
    188                         else
    189                         {
    190                             PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad m= line format for ports info"));
    191                             return SDP_BAD_MEDIA_FORMAT;
    192                         }
    193                     }
    194                     //get the transport profile
    195                     sptr = skip_whitespace(eptr, line_end_ptr);
    196                     if (sptr >= line_end_ptr)
    197                     {
    198                         PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad m= line format for tranport profile"));
    199                         return SDP_BAD_MEDIA_FORMAT;
    200                     }
    201 
    202                     eptr = skip_to_whitespace(sptr, line_end_ptr);
    203                     if (eptr <= sptr)
    204                     {
    205                         PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad m= line format for tranport profile"));
    206                         return SDP_BAD_MEDIA_FORMAT;
    207                     }
    208 
    209                     memFrag.ptr = (void*)sptr;
    210                     memFrag.len = (eptr - sptr);
    211 
    212                     if (oscl_strncmp(sptr, "RTP/AVP", (eptr - sptr)) && oscl_strncmp(sptr, "RTP/AVPF", (eptr - sptr)) && oscl_strncmp(sptr, "RTP/SAVP", (eptr - sptr)))
    213                     {
    214                         PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad m= line format for tranport profile"));
    215                         return SDP_BAD_MEDIA_FORMAT;
    216                     }
    217                     else if ((suggestedPort % 2)) // port number should be even
    218                     {
    219                         PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad m= line format - port number is not even"));
    220                         return SDP_BAD_MEDIA_FORMAT;
    221                     }
    222 
    223                     mediaStr->setTransportProfile(memFrag);
    224 
    225                     //get the payload number
    226                     sptr = skip_whitespace(eptr, line_end_ptr);
    227                     if (sptr >= line_end_ptr)
    228                     {
    229                         PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad m= line format for payload number"));
    230                         return SDP_BAD_MEDIA_FORMAT;
    231                     }
    232 
    233                     while (eptr < line_end_ptr)
    234                     {
    235                         eptr = skip_to_whitespace(sptr, line_end_ptr);
    236                         if (eptr <= sptr)
    237                         {
    238                             PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad m= line format for payload number"));
    239                             return SDP_BAD_MEDIA_FORMAT;
    240                         }
    241 
    242                         uint32 payloadNumber; ;
    243                         if (PV_atoi(sptr, 'd', (eptr - sptr), payloadNumber) == true)
    244                         {
    245                             // Parse the payload number info only and see if there
    246                             // is any payload number in static range if yes rtpmap
    247                             // field may not be present for this
    248                             for (uint32 ii = 0; ii < mediaStr->getPayloadSpecificInfoVector().size(); ii++)
    249                             {
    250                                 if (payloadNumber == mediaStr->getPayloadSpecificInfoVector()[ii]->getPayloadNumber())
    251                                 {
    252                                     // check if (FIRST_STATIC_PAYLOAD <= payloadNumber <= LAST_STATIC_PAYLOAD)
    253                                     // since payloadNumber is unsigned and FIRST_STATIC_PAYLOAD == 0, only the upper
    254                                     // boundary needs to be checked. Adding the lower boundary causes compiler warning.
    255                                     if (payloadNumber <= LAST_STATIC_PAYLOAD)
    256                                         a_rtpmap_found = true;
    257                                 }
    258                             }
    259                         }
    260                         else
    261                         {
    262                             PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad m= line format for payload number"));
    263                             return SDP_BAD_MEDIA_FORMAT;
    264                         }
    265 
    266                         sptr = skip_whitespace(eptr, line_end_ptr);
    267                         eptr = sptr;
    268                     }
    269                     // No rtpmap will come if port is 0 in sip sdp
    270                     if (isSipSdp && suggestedPort == 0)
    271                     {
    272                         a_rtpmap_found = true;
    273                     }
    274 
    275                 }
    276                 break;
    277                 case 'a':
    278                 {
    279                     if (*(line_start_ptr + 1) != '=')
    280                     {
    281                         PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad a= line format - '=' missing"));
    282                         return SDP_BAD_MEDIA_FORMAT;
    283                     }
    284 
    285                     // parse through each field
    286                     const char *sptr1, *eptr1;
    287                     if (!oscl_strncmp(line_start_ptr, "a=rtpmap:", oscl_strlen("a=rtpmap:")))
    288                     {
    289                         //get the payload number
    290                         sptr1 = line_start_ptr + oscl_strlen("a=rtpmap:");
    291                         sptr1 = skip_whitespace(sptr1, line_end_ptr);
    292 
    293                         a_rtpmap_found = true;
    294 
    295                         if (sptr1 >= line_end_ptr)
    296                         {
    297                             PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad a=rtpmap line format"));
    298                             return SDP_BAD_MEDIA_RTP_MAP;
    299                         }
    300                         eptr1 = skip_to_whitespace(sptr1, line_end_ptr);
    301                         if (eptr1 <= sptr1)
    302                         {
    303                             PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad a=rtpmap line format"));
    304                             return SDP_BAD_MEDIA_RTP_MAP;
    305                         }
    306                         uint32 payloadNumber;
    307                         if (PV_atoi(sptr1, 'd', (eptr1 - sptr1), payloadNumber) == true)
    308                         {
    309                             int p;
    310                             if (!mediaStr->lookupPayloadNumber(payloadNumber, p))
    311                             {
    312                                 break;
    313                             }
    314                         }
    315                         else
    316                         {
    317                             PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad a=rtpmap line format for payload number"));
    318                             return SDP_BAD_MEDIA_RTP_MAP;
    319                         }
    320 
    321                         // payloadNumber is present in the mediaInfo. get the payload
    322                         // Specific pointer corresponding to this payload
    323                         PayloadSpecificInfoTypeBase* payloadPtr =
    324                             mediaStr->getPayloadSpecificInfoTypePtr(payloadNumber);
    325                         if (payloadPtr == NULL)
    326                         {
    327                             PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Unable to get payload pointer for the payload"));
    328                             return SDP_PAYLOAD_MISMATCH;
    329                         }
    330                         PVMF_SDP_PARSER_LOGINFO((0, "SDPBaseMediaInfoParser::parseMediaInfo - processing payload number : %d", payloadNumber));
    331 
    332                         //get the MIME type and sample rate
    333                         sptr1 = skip_whitespace(eptr1, line_end_ptr);
    334                         if (sptr1 >= line_end_ptr)
    335                         {
    336                             PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad a=rtpmap line format for MIME Type & Sample rate"));
    337                             return SDP_BAD_MEDIA_RTP_MAP;
    338                         }
    339 
    340                         eptr1 = skip_to_whitespace(sptr1, line_end_ptr);
    341                         if (eptr1 <= sptr1)
    342                         {
    343                             PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad a=rtpmap line format"));
    344                             return SDP_BAD_MEDIA_RTP_MAP;
    345                         }
    346                         //int ii = 0;
    347                         const char *tmp_end_ptr = NULL;
    348                         /*
    349                         for( ii = 0; ii < (eptr1-sptr1); ii++ )
    350                         {
    351                         if(sptr1[ii] == '/')
    352                         {
    353                         tmp_end_ptr = sptr1 + ii;
    354                         break;
    355                         }
    356                         }
    357                         */
    358                         const char SDP_FWD_SLASH[] = "/";
    359                         tmp_end_ptr = oscl_strstr(sptr1, SDP_FWD_SLASH);
    360                         if (tmp_end_ptr == NULL)
    361                         {
    362                             PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad a=rtpmap line format - nothing after '/' "));
    363                             return SDP_BAD_MEDIA_RTP_MAP;
    364                         }
    365                         //The below mentioned code converts the non standard MIME type to standard MIME type.
    366                         //For eg. earlier we have MIME type "AMR" and according to standard it should be
    367                         //like "audio/AMR". so tho whole logic implements the same.
    368                         uint32  tempBufLen = 0;
    369                         char *tmpBuf = NULL;
    370                         const char SDP_NULL[] = "\0";
    371 
    372                         tempBufLen = oscl_strlen(mediaStr->getType()) + (tmp_end_ptr - sptr1) + 2;
    373 
    374                         // "OSCL_TRY(err, OSCL_ARRAY_NEW(char, tempBufLen)" is in separate function to avoid warnings
    375                         newTmpBuf(tempBufLen, &tmpBuf);
    376                         if (NULL == tmpBuf)
    377                         {
    378                             return SDP_NO_MEMORY;
    379                         }
    380 
    381                         oscl_strncpy(tmpBuf, mediaStr->getType(), (oscl_strlen(mediaStr->getType()) + 1));
    382                         oscl_strcat(tmpBuf, SDP_FWD_SLASH);
    383                         oscl_strncat(tmpBuf, sptr1, (tmp_end_ptr - sptr1));
    384                         oscl_strcat(tmpBuf, SDP_NULL);
    385 
    386 
    387                         memFrag.ptr = (void*)tmpBuf;
    388                         memFrag.len = oscl_strlen(tmpBuf);
    389 
    390                         mediaStr->setMIMEType(memFrag);
    391                         OSCL_ARRAY_DELETE(tmpBuf);
    392                         tmpBuf = NULL;
    393                         //Till here
    394                         tmp_end_ptr++;
    395                         if (tmp_end_ptr >= eptr1)
    396                         {
    397                             return SDP_BAD_MEDIA_RTP_MAP;
    398                         }
    399                         tmp_end_ptr = skip_whitespace(tmp_end_ptr, eptr1);
    400                         if (tmp_end_ptr >= eptr1)
    401                         {
    402                             return SDP_BAD_MEDIA_RTP_MAP;
    403                         }
    404 
    405                         OSCL_HeapString<SDPParserAlloc> restOfLine(tmp_end_ptr, eptr1 - tmp_end_ptr);
    406                         const char *another_slash = oscl_strstr(restOfLine.get_cstr(), SDP_FWD_SLASH);
    407 
    408                         uint32 sampleRate;
    409                         if (another_slash)
    410                         {
    411                             if (PV_atoi(restOfLine.get_cstr(), 'd', (another_slash - restOfLine.get_cstr()), sampleRate) == true)
    412                             {
    413                                 payloadPtr->setSampleRate(sampleRate);
    414                                 // There must be channel numbers after the 2nd forward slash
    415                                 uint32 channels;
    416                                 tmp_end_ptr = oscl_strstr(tmp_end_ptr, SDP_FWD_SLASH);
    417                                 if (tmp_end_ptr == NULL)
    418                                 {
    419                                     PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad a=rtpmap line format for channel info"));
    420                                     return SDP_BAD_MEDIA_RTP_MAP;
    421                                 }
    422                                 tmp_end_ptr++;
    423                                 if (PV_atoi(tmp_end_ptr, 'd', (eptr1 - tmp_end_ptr), channels) == true)
    424                                 {
    425                                     payloadPtr->setNoOfChannels(channels);
    426                                 }
    427                                 else
    428                                 {
    429                                     PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad a=rtpmap line format for channel info"));
    430                                     return SDP_BAD_MEDIA_RTP_MAP;
    431                                 }
    432                             }
    433                             else
    434                             {
    435                                 PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad a=rtpmap line format for channel info"));
    436                                 return SDP_BAD_MEDIA_RTP_MAP;
    437                             }
    438                         }
    439                         else
    440                         {
    441                             if (PV_atoi(tmp_end_ptr, 'd', (eptr1 - tmp_end_ptr), sampleRate) == true)
    442                             {
    443                                 payloadPtr->setSampleRate(sampleRate);
    444                             }
    445                             else
    446                             {
    447                                 return SDP_BAD_MEDIA_RTP_MAP;
    448                             }
    449                         }
    450                     }
    451                     if (!oscl_strncmp(line_start_ptr, "a=control:", oscl_strlen("a=control:")))
    452                     {
    453                         sptr1 = line_start_ptr + oscl_strlen("a=control:");
    454                         sptr1 = skip_whitespace(sptr1, line_end_ptr);
    455                         a_control_found = true;
    456                         if (sptr1 >= line_end_ptr)
    457                         {
    458                             return SDP_BAD_MEDIA_CONTROL_FIELD;
    459                         }
    460 
    461                         memFrag.ptr = (void*)sptr1;
    462                         memFrag.len = (line_end_ptr - sptr1);
    463                         mediaStr->setControlURL(memFrag);
    464 
    465                         for (int ii = 0; ii < (line_end_ptr - sptr1); ii++)
    466                         {
    467                             if (sptr1[ii] == '=')
    468                             {
    469                                 uint32 trackID;
    470                                 sptr1 = skip_whitespace((sptr1 + ii + 1), line_end_ptr);
    471                                 if (sptr1 >= line_end_ptr)
    472                                 {
    473                                     break;
    474                                 }
    475 
    476                                 if ((PV_atoi(sptr1, 'd', 1, trackID) == true))
    477                                 {
    478                                     mediaStr->setControlTrackID(trackID);
    479                                 }
    480                                 break;
    481                             }
    482                         }
    483                     }
    484                     if (!oscl_strncmp(line_start_ptr, "a=range:", oscl_strlen("a=range:")))
    485                     {
    486                         sptr1 = line_start_ptr + oscl_strlen("a=range:");
    487                         sptr1 = skip_whitespace(sptr1, line_end_ptr);
    488 
    489                         a_range_found = true;
    490 
    491                         if (sptr1 >= line_end_ptr)
    492                         {
    493                             return SDP_BAD_MEDIA_RANGE_FIELD;
    494                         }
    495                         parseRtspRange(sptr1, line_end_ptr - sptr1, *(mediaStr->getRtspRange()));
    496                     }
    497                     if (!oscl_strncmp(line_start_ptr, "a=depends_on:", oscl_strlen("a=depends_on:")))
    498                     {
    499                         sptr1 = line_start_ptr + oscl_strlen("a=depends_on:");
    500                         memFrag.ptr = (void*)sptr1;
    501                         memFrag.len = (line_end_ptr - sptr1);
    502                         mediaStr->setDependsonURL(memFrag);
    503 
    504                         for (int ii = 0; ii < (line_end_ptr - sptr1); ii++)
    505                         {
    506                             if (sptr1[ii] == '=')
    507                             {
    508                                 uint32 trackID;
    509                                 sptr1 = skip_whitespace((sptr1 + ii + 1), line_end_ptr);
    510                                 if (sptr1 >= line_end_ptr)
    511                                 {
    512                                     break;
    513                                 }
    514 
    515                                 if ((PV_atoi(sptr1, 'd', 1, trackID) == true))
    516                                 {
    517                                     mediaStr->setDependsOnTrackID(trackID);
    518                                 }
    519                                 break;
    520                             }
    521                         }
    522                     }
    523 
    524                     //Random access denied added for 3rd party content random positioning - 01/08/02
    525                     StrPtrLen random_access("a=random_access_denied");
    526                     if (!oscl_strncmp(line_start_ptr, random_access.c_str(), random_access.length()))
    527                     {
    528                         mediaStr->setRandomAccessDenied(true);
    529                     }
    530 
    531                     StrPtrLen qoe_metrics("a=3GPP-QoE-Metrics:");
    532                     if (!oscl_strncmp(line_start_ptr, qoe_metrics.c_str(), qoe_metrics.length()))
    533                     {
    534                         const char *sptr;
    535                         sptr = line_start_ptr + qoe_metrics.length();
    536                         QoEMetricsType qMetrics;
    537                         oscl_memset(qMetrics.name, 0, 7);
    538                         qMetrics.rateFmt = QoEMetricsType::VAL;
    539                         qMetrics.rateVal = 0;
    540                         qMetrics.paramFmt = QoEMetricsType::IDIGIT;
    541                         qMetrics.paramExtIdigit = 0;
    542 
    543                         if (!parseQoEMetrics(sptr, line_end_ptr, qMetrics))
    544                         {
    545                             PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad a=3GPP-QoE-Metrics: line format"));
    546                             return SDP_BAD_MEDIA_FORMAT;
    547                         }
    548                         mediaStr->setQoEMetrics(qMetrics);
    549 
    550 
    551                     }
    552                     StrPtrLen predec("a=X-predecbufsize:");
    553                     if (!oscl_strncmp(line_start_ptr, predec.c_str(), predec.length()))
    554                     {
    555                         const char *sptr;
    556                         sptr = line_start_ptr + predec.length();
    557                         uint32 size;
    558                         if (!PV_atoi(sptr, 'd', (line_end_ptr - sptr), size))
    559                         {
    560                             PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad a=X-predecbufsize: line format"));
    561                             return SDP_BAD_MEDIA_FORMAT;
    562                         }
    563                         mediaStr->setPreDecBuffSize(size);
    564                     }
    565 
    566                     StrPtrLen initpredec("a=X-initpredecbufperiod:");
    567                     if (!oscl_strncmp(line_start_ptr, initpredec.c_str(), initpredec.length()))
    568                     {
    569                         const char *sptr;
    570                         sptr = line_start_ptr + initpredec.length();
    571                         uint32 period;
    572                         if (!PV_atoi(sptr, 'd', (line_end_ptr - sptr), period))
    573                         {
    574                             PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad a=X-initpredecbufperiod: line format"));
    575                             return SDP_BAD_MEDIA_FORMAT;
    576                         }
    577                         mediaStr->setInitPreDecBuffPeriod(period);
    578                     }
    579 
    580                     StrPtrLen initpostdec("a=X-initpostdecbufperiod:");
    581                     if (!oscl_strncmp(line_start_ptr, initpostdec.c_str(), initpostdec.length()))
    582                     {
    583                         const char *sptr;
    584                         sptr = line_start_ptr + initpostdec.length();
    585                         uint32 period;
    586                         if (!PV_atoi(sptr, 'd', (line_end_ptr - sptr), period))
    587                         {
    588                             PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad a=X-initpostdecbufperiod: line format"));
    589                             return SDP_BAD_MEDIA_FORMAT;
    590                         }
    591                         mediaStr->setInitPostDecBuffPeriod(period);
    592                     }
    593 
    594                     StrPtrLen decbyterate("a=X-decbyterate:");
    595                     if (!oscl_strncmp(line_start_ptr, decbyterate.c_str(),
    596                                       decbyterate.length()))
    597                     {
    598                         const char *sptr;
    599                         sptr = line_start_ptr + decbyterate.length();
    600                         uint32 rate;
    601                         if (!PV_atoi(sptr, 'd', (line_end_ptr - sptr), rate))
    602                         {
    603                             PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad a=X-decbyterate: line format"));
    604                             return SDP_BAD_MEDIA_FORMAT;
    605                         }
    606                         mediaStr->setDecByteRate(rate);
    607                     }
    608 
    609                     StrPtrLen adapt_supp("a=3GPP-Adaptation-Support:");
    610                     if (!oscl_strncmp(line_start_ptr, adapt_supp.c_str(),
    611                                       adapt_supp.length()))
    612                     {
    613                         const char *sptr = line_start_ptr + adapt_supp.length();
    614                         sptr = skip_whitespace_and_line_term(sptr, line_end_ptr);
    615                         uint32 frequency;
    616                         if (!PV_atoi(sptr, 'd', line_end_ptr - sptr, frequency))
    617                         {
    618                             PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad a=3GPP-Adaptation-Support: line format - frequency not correct"));
    619                             return SDP_BAD_MEDIA_FORMAT;
    620                         }
    621                         mediaStr->setReportFrequency(frequency);
    622                     }
    623 
    624                     StrPtrLen asset_info("a=3GPP-Asset-Information:");
    625                     if (!oscl_strncmp(line_start_ptr, asset_info.c_str(),
    626                                       asset_info.length()))
    627                     {
    628                         const char *sptr = line_start_ptr + asset_info.length();
    629                         AssetInfoType assetInfo;
    630                         if (!parseAssetInfo(sptr, line_end_ptr, assetInfo))
    631                         {
    632                             PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad a=3GPP-Asset-Information: line format"));
    633                             return SDP_BAD_SESSION_FORMAT;
    634                         }
    635 
    636                         mediaStr->setAssetInfo(assetInfo);
    637 
    638                     }
    639                     StrPtrLen srtp("a=3GPP-SRTP-Config:");
    640                     if (!oscl_strncmp(line_start_ptr, srtp.c_str(),
    641                                       srtp.length()))
    642                     {
    643                         const char *sptr = line_start_ptr + srtp.length();
    644                         const char *eptr;
    645                         sptr = skip_whitespace(sptr, line_end_ptr);
    646                         eptr = skip_to_whitespace(sptr, line_end_ptr);
    647                         memFrag.ptr = (void *)sptr;
    648                         memFrag.len = eptr - sptr;
    649 
    650                         mediaStr->setSRTPintg_nonce(memFrag);
    651 
    652                         eptr = eptr + 1;
    653                         sptr = eptr;
    654                         if (sptr >= line_end_ptr)
    655                         {
    656                             PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad a=3GPP-SRTP-Config: line format"));
    657                             return SDP_BAD_MEDIA_FORMAT;
    658                         }
    659                         eptr = skip_to_whitespace(eptr, line_end_ptr);
    660                         if (eptr >= line_end_ptr)
    661                         {
    662                             PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad a=3GPP-SRTP-Config: line format"));
    663                             return SDP_BAD_MEDIA_FORMAT;
    664                         }
    665 
    666                         memFrag.ptr = (void *)sptr;
    667                         memFrag.len = eptr - sptr;
    668                         mediaStr->setSRTPkey_salt(memFrag);
    669 
    670                         eptr = eptr + 1;
    671                         sptr = eptr;
    672 
    673                         if (!oscl_strncmp(sptr, "auth-tag-len=", oscl_strlen("auth-tag-len=")))
    674                         {
    675                             sptr = sptr + oscl_strlen("auth-tag-len=");
    676                             uint32 length;
    677                             if (!PV_atoi(sptr, 'd', 2, length))
    678                             {
    679                                 PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad a=3GPP-SRTP-Config: line format for auth-tag-len= field"));
    680                                 return SDP_BAD_MEDIA_FORMAT;
    681                             }
    682                             if ((length != 32) && (length != 80))
    683                             {
    684                                 PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad a=3GPP-SRTP-Config: line format for auth-tag-len= field"));
    685                                 return SDP_BAD_MEDIA_FORMAT;
    686                             }
    687                             else
    688                                 mediaStr->setSRTPauth_tag_len(length);
    689 
    690                         }
    691                         else
    692                         {
    693                             memFrag.ptr = (void *)sptr;
    694                             memFrag.len = line_end_ptr - sptr;
    695 
    696                             mediaStr->setSRTPparam_ext(memFrag);
    697 
    698 
    699                         }
    700 
    701 
    702                     }
    703                     StrPtrLen rtcp_fb("a=rtcp-fb:");
    704                     if (!oscl_strncmp(line_start_ptr, rtcp_fb.c_str(), rtcp_fb.length()))
    705                     {
    706                         const char *sptr = line_start_ptr + rtcp_fb.length();
    707                         const char *eptr = skip_to_whitespace(sptr, line_end_ptr);
    708 
    709                         if (eptr >= line_end_ptr)
    710                         {
    711                             PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad a=rtcp-fb: line format"));
    712                             return SDP_BAD_MEDIA_FORMAT;
    713                         }
    714 
    715                         memFrag.ptr = (void *)sptr;
    716                         memFrag.len = eptr - sptr;
    717                         mediaStr->setrtcp_fb_pt(memFrag);
    718 
    719                         sptr = skip_whitespace(eptr, line_end_ptr);
    720                         eptr = skip_to_whitespace(sptr, line_end_ptr);
    721 
    722                         memFrag.ptr = (void *)sptr;
    723                         memFrag.len = eptr - sptr;
    724                         mediaStr->setrtcp_fb_val(memFrag);
    725 
    726                         if (eptr >= line_end_ptr)
    727                             break;
    728 
    729                         if (!oscl_strncmp(sptr, "trr-int", eptr - sptr))
    730                         {
    731                             sptr = skip_whitespace(eptr, line_end_ptr);
    732                             eptr = skip_to_line_term(sptr, line_end_ptr);
    733                             uint32 trr;
    734                             if (!PV_atoi(sptr, 'd', eptr - sptr, trr))
    735                             {
    736                                 PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad a=rtcp-fb: line format for trr-int field"));
    737                                 return SDP_BAD_MEDIA_FORMAT;
    738                             }
    739 
    740                             mediaStr->setrtcp_fb_trr_val(trr);
    741                         }
    742                         else
    743                         {
    744                             sptr = skip_whitespace(eptr, line_end_ptr);
    745                             eptr = skip_to_line_term(sptr, line_end_ptr);
    746                             memFrag.ptr = (void *)sptr;
    747                             memFrag.len = eptr - sptr;
    748                             mediaStr->setrtcp_fb_val_param(memFrag);
    749 
    750                         }
    751 
    752 
    753                     }
    754                     if (!oscl_strncmp(line_start_ptr, "a=alt:", oscl_strlen("a=alt:")))
    755                     {
    756                         line_start_ptr += oscl_strlen("a=alt:");
    757                         const char *end1 = line_start_ptr;
    758                         for (; *end1 != ':'; end1++);
    759                         uint32 id;
    760                         if (!PV_atoi(line_start_ptr, 'd' , end1 - line_start_ptr, id))
    761                         {
    762                             PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad ID in a=alt: line format"));
    763                             return SDP_BAD_MEDIA_ALT_ID;
    764                         }
    765 
    766                         //check if id is already present
    767                         Oscl_Vector<int, SDPParserAlloc> alt_track = mediaStr->getalternateTrackId();
    768                         bool found = false;
    769                         for (int ss = 0; ss < (int)alt_track.size(); ss++)
    770                         {
    771                             if (alt_track[ss] == (int)id)
    772                                 found = true;
    773                         }
    774                         if (!found)
    775                             mediaStr->setalternateTrackId(id);
    776                     }
    777                     if (!oscl_strncmp(line_start_ptr, "a=maxprate:", oscl_strlen("a=maxprate:")))
    778                     {
    779                         line_start_ptr += oscl_strlen("a=maxprate:");
    780                         OsclFloat rate;
    781                         if (!PV_atof(line_start_ptr, line_end_ptr - line_start_ptr, rate))
    782                         {
    783                             PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad a=maxprate: line format for rate field"));
    784                             return SDP_BAD_MEDIA_FORMAT;
    785                         }
    786                         mediaStr->setMaxprate(rate);
    787                     }
    788                     if (!oscl_strncmp(line_start_ptr, "a=X-allowrecord", oscl_strlen("a=X-allowrecord")))
    789                     {
    790                         mediaStr->setAllowRecord(true);
    791                     }
    792 
    793                 }
    794                 break;
    795                 case 'b':
    796                 {
    797                     if (!oscl_strncmp(line_start_ptr, "b=AS:", oscl_strlen("b=AS:")))
    798                     {
    799                         const char *sptr;
    800                         sptr = line_start_ptr + oscl_strlen("b=AS:");
    801                         sptr = skip_whitespace(sptr, line_end_ptr);
    802                         if (sptr >= line_end_ptr)
    803                         {
    804                             PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad b=AS: line format"));
    805                             return SDP_BAD_MEDIA_FORMAT;
    806                         }
    807 
    808                         uint32 bitRate;
    809                         if (PV_atoi(sptr, 'd', (line_end_ptr - sptr),  bitRate) == true)
    810                         {
    811                             mediaStr->setBitrate(1000*bitRate);
    812                         }
    813                         else
    814                         {
    815                             PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad b=AS: line format - bitrate incorrect"));
    816                             return SDP_BAD_MEDIA_FORMAT;
    817                         }
    818                     }
    819                     else if (!oscl_strncmp(line_start_ptr, "b=RS:", oscl_strlen("b=RS:")))
    820                     {
    821                         const char *sptr;
    822                         sptr = line_start_ptr + oscl_strlen("b=AS:");
    823                         sptr = skip_whitespace(sptr, line_end_ptr);
    824                         if (sptr >= line_end_ptr)
    825                         {
    826                             PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad b=RS: line format"));
    827                             return SDP_BAD_MEDIA_FORMAT;
    828                         }
    829 
    830                         uint32 rtcpBWSender;
    831                         if (PV_atoi(sptr, 'd', (line_end_ptr - sptr),  rtcpBWSender) == true)
    832                         {
    833                             mediaStr->setRTCPSenderBitRate(rtcpBWSender);
    834                         }
    835                         else
    836                         {
    837                             PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad b=RS: line format - Sender Bitrate incorrect"));
    838                             return SDP_BAD_MEDIA_FORMAT;
    839                         }
    840                     }
    841                     else if (!oscl_strncmp(line_start_ptr, "b=RR:", oscl_strlen("b=RR:")))
    842                     {
    843                         const char *sptr;
    844                         sptr = line_start_ptr + oscl_strlen("b=AS:");
    845                         sptr = skip_whitespace(sptr, line_end_ptr);
    846                         if (sptr >= line_end_ptr)
    847                         {
    848                             PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad b=RR: line format"));
    849                             return SDP_BAD_MEDIA_FORMAT;
    850                         }
    851 
    852                         uint32 rtcpBWReceiver;
    853                         if (PV_atoi(sptr, 'd', (line_end_ptr - sptr),  rtcpBWReceiver) == true)
    854                         {
    855                             mediaStr->setRTCPReceiverBitRate(rtcpBWReceiver);
    856                         }
    857                         else
    858                         {
    859                             PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad b=RR: line format - Receiver Bit rate incorrect"));
    860                             return SDP_BAD_MEDIA_FORMAT;
    861                         }
    862                     }
    863                     else if (!oscl_strncmp(line_start_ptr, "b=TIAS:", oscl_strlen("b=TIAS:")))
    864                     {
    865                         const char *sptr;
    866                         sptr = line_start_ptr + oscl_strlen("b=TIAS:");
    867                         sptr = skip_whitespace(sptr, line_end_ptr);
    868                         if (sptr >= line_end_ptr)
    869                         {
    870                             PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad b=T1AS: line format"));
    871                             return SDP_BAD_MEDIA_FORMAT;
    872                         }
    873 
    874                         uint32 bMod;
    875                         if (PV_atoi(sptr, 'd', (line_end_ptr - sptr),  bMod) == true)
    876                         {
    877                             mediaStr->setBWtias(1000 * bMod);
    878                         }
    879                         else
    880                         {
    881                             PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad b=T1AS: line format - bMod incorrect"));
    882                             return SDP_BAD_MEDIA_FORMAT;
    883                         }
    884                     }
    885                 }
    886                 break;
    887                 case 'u':
    888                 {
    889                     PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - u field not supported"));
    890                     return SDP_BAD_MEDIA_FORMAT;
    891                 }
    892                 case 'c':
    893                 {
    894                     if (*(line_start_ptr + 1) != '=')
    895                     {
    896                         PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad c= line format - '=' missing after c"));
    897                         return SDP_BAD_SESSION_FORMAT;
    898                     }
    899 
    900                     mediaStr->setCFieldStatus(true);
    901 
    902                     // parse through each field
    903                     const char *sptr, *eptr;
    904 
    905                     // get the connection network type
    906                     sptr = skip_whitespace(line_start_ptr + 2, line_end_ptr);
    907                     if (sptr >= line_end_ptr)
    908                     {
    909                         PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad c= line format - connection network type missing"));
    910                         return SDP_BAD_SESSION_FORMAT;
    911                     }
    912 
    913                     eptr = skip_to_whitespace(sptr, line_end_ptr);
    914                     if (eptr <= sptr)
    915                     {
    916                         PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad c= line format - part after connection network type missing"));
    917                         return SDP_BAD_SESSION_FORMAT;
    918                     }
    919 
    920                     memFrag.ptr = (void*)sptr;
    921                     memFrag.len = (eptr - sptr);
    922                     mediaStr->setCNetworkType(memFrag);
    923 
    924                     // get the address type
    925                     sptr = skip_whitespace(eptr, line_end_ptr);
    926                     if (sptr >= line_end_ptr)
    927                     {
    928                         PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad c= line format - address type missing"));
    929                         return SDP_BAD_SESSION_FORMAT;
    930                     }
    931 
    932                     eptr = skip_to_whitespace(sptr, line_end_ptr);
    933                     if (eptr <= sptr)
    934                     {
    935                         PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad c= line format - part after address type missing"));
    936                         return SDP_BAD_SESSION_FORMAT;
    937                     }
    938                     memFrag.ptr = (void*)sptr;
    939                     memFrag.len = (eptr - sptr);
    940                     mediaStr->setCAddressType(memFrag);
    941 
    942                     // get the address
    943                     sptr = skip_whitespace(eptr, line_end_ptr);
    944                     if (sptr >= line_end_ptr)
    945                     {
    946                         PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad c= line format - address missing"));
    947                         return SDP_BAD_SESSION_FORMAT;
    948                     }
    949 
    950                     eptr = skip_to_whitespace(sptr, line_end_ptr);
    951                     if (eptr < sptr)
    952                     {
    953                         PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad c= line format - part after address missing"));
    954                         return SDP_BAD_SESSION_FORMAT;
    955                     }
    956                     memFrag.ptr = (void*)sptr;
    957                     memFrag.len = (eptr - sptr);
    958                     mediaStr->setCAddress(memFrag);
    959                     uint32 len = OSCL_MIN((uint32)(eptr - sptr), oscl_strlen("IP4"));
    960                     if (oscl_strncmp(sptr, "IP4", len) == 0)
    961                     {
    962                         uint32 address;
    963                         const char *addrend = sptr;
    964                         for (; *addrend != '.'; ++addrend);
    965 
    966                         if (!PV_atoi(sptr, 'd', addrend - sptr, address))
    967                         {
    968                             PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad c= line format"));
    969                             return SDP_BAD_SESSION_FORMAT;
    970                         }
    971 
    972                         if (address >= 224 && address <= 239) //multicast address look for TTL
    973                         {
    974                             for (; (*sptr != '/') && (sptr < eptr); ++sptr);
    975                             if (sptr == eptr)
    976                             {
    977                                 PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad c= line format"));
    978                                 return SDP_BAD_SESSION_FORMAT; // no TTL found in multicast address.
    979                             }
    980                             else
    981                             {
    982                                 uint32 ttl;
    983                                 sptr = sptr + 1;
    984                                 if (!PV_atoi(sptr, 'd', eptr - sptr, ttl))
    985                                 {
    986                                     PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad c= line format"));
    987                                     return SDP_BAD_SESSION_FORMAT;
    988                                 }
    989                                 if (!(ttl <= 255))
    990                                 {
    991                                     PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad c= line format"));
    992                                     return SDP_BAD_SESSION_FORMAT; // ttl out of range.
    993                                 }
    994 
    995                             }
    996 
    997                         }
    998                         else  // unicast address
    999                         {
   1000                             for (; (*sptr != '/') && (sptr < eptr); ++sptr);
   1001                             if (!oscl_strncmp(sptr, "/", 1))
   1002                             {
   1003                                 PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad c= line format"));
   1004                                 return SDP_BAD_SESSION_FORMAT; //unicast address can not have TTL.
   1005                             }
   1006                         }
   1007 
   1008                         if (eptr < line_end_ptr)
   1009                         {
   1010                             PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad c= line format"));
   1011                             return SDP_BAD_SESSION_FORMAT;
   1012                         }
   1013                     }
   1014                     //use "len" here since "IP4" and "IP6" have same lengths
   1015                     else if (oscl_strncmp(sptr, "IP6", len) == 0)
   1016                     {
   1017                         //TBD
   1018                     }
   1019                     break;
   1020                 }
   1021 
   1022                 default:
   1023                 {
   1024                     //skip a line we don't understand
   1025                 }
   1026                 break;
   1027             }
   1028         }
   1029         current_start = line_end_ptr;
   1030     }
   1031 
   1032     mediaStr->setmediaTrackId(alt_id);
   1033 
   1034     if (!alt_def_id && alt_id)
   1035     {
   1036         uint32 defaultId;
   1037         getAltDefaultId(buff, buff + index, defaultId);
   1038         if (defaultId != 0)
   1039             mediaStr->setalternateTrackId(defaultId);
   1040         else
   1041             return SDP_BAD_MEDIA_ALT_ID;
   1042     }
   1043 
   1044     if (!a_control_found)
   1045     {
   1046         uint32 addr;
   1047         connectionInfo ci;
   1048         mediaStr->getConnectionInformation(&ci);
   1049         PV_atoi(ci.connectionAddress.get_cstr(), 'd', addr);
   1050         //224.0.0.0 through 239.255.255.255 represent class D network addresses
   1051         //reserved for multicasting, which indicate a DVB connection
   1052         if (addr >= 224 && addr <= 239)
   1053         {
   1054             uint32 id = mediaStr->getMediaInfoID();
   1055             mediaStr->setControlTrackID(id);
   1056             a_control_set = true;
   1057         }
   1058     }
   1059 
   1060     /*
   1061      * cannot assume that range is always going to be set at media level
   1062      */
   1063     if ((isSipSdp && a_rtpmap_found) || (!alt_def_id && alt_id))
   1064         return SDP_SUCCESS;
   1065     else if ((a_rtpmap_found && a_control_found) || (!alt_def_id && alt_id) || (a_control_set))
   1066         return SDP_SUCCESS;
   1067     else
   1068     {
   1069         PVMF_SDP_PARSER_LOGERROR((0, "SDPBaseMediaInfoParser::parseMediaInfo - Bad Media - no rtpmap and control present"));
   1070         return SDP_BAD_MEDIA_FORMAT;
   1071     }
   1072 }
   1073 
   1074 
   1075 SDP_ERROR_CODE SDPBaseMediaInfoParser::getAltDefaultId(const char* start, const char *end, uint32 &defaultId)
   1076 {
   1077     const char *current_start = start;
   1078     const char *line_start_ptr, *line_end_ptr;
   1079     defaultId = 0;
   1080     while (get_next_line(current_start, end,
   1081                          line_start_ptr, line_end_ptr))
   1082     {
   1083         switch (*line_start_ptr)
   1084         {
   1085             case 'a':
   1086             {
   1087                 if (!oscl_strncmp(line_start_ptr, "a=alt-default-id:", oscl_strlen("a=alt-default-id:")))
   1088                 {
   1089                     line_start_ptr += oscl_strlen("a=alt-default-id:");
   1090 
   1091                     if (!PV_atoi(line_start_ptr, 'd', line_end_ptr - line_start_ptr, defaultId))
   1092                         return SDP_BAD_MEDIA_ALT_ID;
   1093                     else
   1094                         return SDP_SUCCESS;
   1095 
   1096                 }
   1097             }
   1098             break;
   1099             default:
   1100                 break;
   1101 
   1102         }
   1103 
   1104         current_start = line_end_ptr;
   1105     }
   1106 
   1107     return SDP_SUCCESS;
   1108 }
   1109 
   1110 SDP_ERROR_CODE SDPBaseMediaInfoParser::setDependentMediaId(const char *start, int length, mediaInfo *mediaPtr, int mediaId)
   1111 {
   1112     const char *startPtr = start;
   1113     const char *endLine = start + length;
   1114 
   1115     while (startPtr < endLine)
   1116     {
   1117         for (; *startPtr != '='; ++startPtr);
   1118         startPtr = startPtr + 1;
   1119         if (startPtr > endLine)
   1120             return SDP_BAD_MEDIA_ALT_ID;
   1121         const char *endPtr = startPtr;
   1122         for (; (*endPtr != ';') && (endPtr != endLine); ++endPtr);
   1123 
   1124         if (endPtr > endLine)
   1125             return SDP_BAD_MEDIA_ALT_ID;
   1126 
   1127         if (lookForMediaId(startPtr, endPtr, mediaId))
   1128         {
   1129             while (startPtr < endPtr)
   1130             {
   1131                 const char *end = startPtr;
   1132                 for (; (*end != ',') && (end < endPtr) ; ++end);
   1133                 uint32 id;
   1134                 if (!PV_atoi(startPtr, 'd', end - startPtr, id))
   1135                     return SDP_BAD_MEDIA_ALT_ID;
   1136                 if ((int)id != mediaId)
   1137                     mediaPtr->setdependentTrackId(id);
   1138                 startPtr = end + 1;
   1139             }
   1140         }
   1141         else
   1142             startPtr = endPtr + 1;
   1143     }
   1144 
   1145     return SDP_SUCCESS;
   1146 
   1147 }
   1148 
   1149 bool SDPBaseMediaInfoParser::lookForMediaId(const char *startPtr, const char* endPtr, int mediaId)
   1150 {
   1151     const char *end = startPtr;
   1152 
   1153     while (startPtr < endPtr)
   1154     {
   1155         for (; (*end != ',') && (end < endPtr); ++end);
   1156         uint32 id;
   1157         PV_atoi(startPtr, 'd' , end - startPtr, id);
   1158         if ((int)id == mediaId)
   1159             return true;
   1160         end = end + 1;
   1161         startPtr = end;
   1162     }
   1163 
   1164     return false;
   1165 }
   1166 
   1167