• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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                                                       */
newTmpBuf(uint32 len,char ** buf)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
baseMediaInfoParser(const char * buff,mediaInfo * mediaStr,const int index,const int alt_id,bool alt_def_id,bool isSipSdp)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 
getAltDefaultId(const char * start,const char * end,uint32 & defaultId)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 
setDependentMediaId(const char * start,int length,mediaInfo * mediaPtr,int mediaId)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 
lookForMediaId(const char * startPtr,const char * endPtr,int mediaId)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