00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00032 #include "parserpriv.h"
00033
00042 #define NEXT_LINE(c) \
00043 ({ \
00044 while ((*(c) != '\0') && (*(c) != '\r') && (*(c) != '\n')) { \
00045 (c)++; \
00046 } \
00047 if (*(c) == '\n') { \
00048 (c)++; \
00049 } else if (*(c) == '\r') { \
00050 (c)++; \
00051 if (*(c) == '\n') { \
00052 (c)++; \
00053 } else { \
00054 return FSDPE_ILLEGAL_CHARACTER; \
00055 } \
00056 } \
00057 })
00058
00059 fsdp_error_t
00060 fsdp_parse(const char *text_description, fsdp_description_t *dsc)
00061 {
00062 fsdp_error_t result;
00063 const char *p = text_description, *p2;
00064 unsigned int index, j;
00065
00066 const unsigned int TEMPCHARS = 6;
00067 char fsdp_buf[TEMPCHARS][MAXSHORTFIELDLEN];
00068 char longfsdp_buf[MAXLONGFIELDLEN];
00069 const unsigned int TEMPINTS = 2;
00070 unsigned long int wuint[TEMPINTS];
00071
00072 if ( (NULL == text_description) || (NULL == dsc) )
00073 return FSDPE_INVALID_PARAMETER;
00074
00075
00076
00077
00078
00079
00080
00081 if ( sscanf(p,"v=%1lu",&wuint[0]) ){
00082 if ( wuint[0] != 0 )
00083 return FSDPE_INVALID_VERSION;
00084 } else {
00085 return FSDPE_MISSING_VERSION;
00086 }
00087 NEXT_LINE(p);
00088
00089
00090
00091
00092 if ( !strncmp(p,"o=",2) ) {
00093 p += 2;
00094
00095
00096 if ( sscanf(p,"%"MSFLENS"[\x21-\xFF] %"MSFLENS"[0-9] %"MSFLENS"[0-9] %2s %3s %"MSFLENS"s",
00097 fsdp_buf[0],fsdp_buf[1],fsdp_buf[2],fsdp_buf[3],fsdp_buf[4],fsdp_buf[5]) != 6)
00098 return FSDPE_INVALID_OWNER;
00099 dsc->o_username = strdup(fsdp_buf[0]);
00100 dsc->o_session_id = strdup(fsdp_buf[1]);
00101 dsc->o_announcement_version = strdup(fsdp_buf[2]);
00102 if ( !strncmp(fsdp_buf[3],"IN",2) ) {
00103 dsc->o_network_type = FSDP_NETWORK_TYPE_INET;
00104 if ( !strncmp(fsdp_buf[4],"IP4",3) )
00105 dsc->o_address_type = FSDP_ADDRESS_TYPE_IPV4;
00106 else if ( !strncmp(fsdp_buf[4],"IP6",3) )
00107 dsc->o_address_type = FSDP_ADDRESS_TYPE_IPV6;
00108 else
00109 return FSDPE_INVALID_OWNER;
00110 } else {
00111 return FSDPE_INVALID_OWNER;
00112 }
00113
00114 dsc->o_address = strdup(fsdp_buf[5]);
00115 } else {
00116 return FSDPE_MISSING_OWNER;
00117 }
00118 NEXT_LINE(p);
00119
00120
00121
00122 if ( !strncmp(p,"s=",2) ) {
00123 if ( sscanf(p,"s=%"MLFLENS"[^\r\n]",longfsdp_buf) < 1 )
00124 return FSDPE_EMPTY_NAME;
00125 dsc->s_name = strdup(longfsdp_buf);
00126 } else {
00127 return FSDPE_MISSING_NAME;
00128 }
00129 NEXT_LINE(p);
00130
00131
00132
00133 if ( !strncmp(p,"i=",2) && sscanf(p,"i=%"MLFLENS"[^\r\n]",longfsdp_buf) ) {
00134 dsc->i_information = strdup(longfsdp_buf);
00135 NEXT_LINE(p);
00136 } else {
00137
00138 }
00139
00140
00141
00142 if ( !strncmp(p,"u=",2) && sscanf(p,"u=%"MLFLENS"[^\r\n]",longfsdp_buf) ) {
00143
00144 dsc->u_uri = strdup(longfsdp_buf);
00145 NEXT_LINE(p);
00146 } else {
00147
00148 }
00149
00150
00151
00152 p2 = p;
00153 j = 0;
00154 while ( !strncmp(p2,"e=",2) ) {
00155
00156 j++;
00157 NEXT_LINE(p2);
00158 }
00159 dsc->emails_count = j;
00160 if ( dsc->emails_count > 0 ) {
00161
00162 dsc->emails = calloc(j,sizeof(const char *));
00163 for ( j = 0; j < dsc->emails_count; j++) {
00164 sscanf(p,"e=%"MLFLENS"[^\r\n]",longfsdp_buf);
00165
00166 dsc->emails[j] = strdup(longfsdp_buf);
00167 NEXT_LINE(p);
00168 }
00169 }
00170
00171
00172
00173 j = 0;
00174
00175 while ( !strncmp(p2,"p=",2) ) {
00176 j++;
00177 NEXT_LINE(p2);
00178 }
00179 dsc->phones_count = j;
00180 if ( dsc->phones_count > 0 ) {
00181 dsc->phones = calloc(j,sizeof(const char *));
00182 for ( j = 0; j < dsc->phones_count; j++ ) {
00183 sscanf(p,"p=%"MLFLENS"[^\r\n]",longfsdp_buf);
00184
00185 dsc->phones[j] = strdup(longfsdp_buf);
00186 NEXT_LINE(p);
00187 }
00188 }
00189
00190
00191
00192 result = fsdp_parse_c(&p,&(dsc->c_network_type),&(dsc->c_address_type),
00193 &(dsc->c_address));
00194 if ( FSDPE_OK != result )
00195 return result;
00196
00197
00198
00199 result = fsdp_parse_b(&p,&(dsc->bw_modifiers),&(dsc->bw_modifiers_count));
00200 if ( FSDPE_OK != result )
00201 return result;
00202
00203
00204
00205
00206
00207 j = 0;
00208 p2 = p;
00209 while ( !strncmp(p2,"t=",2) ) {
00210 j++;
00211 NEXT_LINE(p2);
00212 while ( !strncmp(p2,"r=",2) )
00213 NEXT_LINE(p2);
00214 }
00215 dsc->time_periods_count = j;
00216 if ( dsc->time_periods_count == 0 )
00217 return FSDPE_MISSING_TIME;
00218 dsc->time_periods = calloc(dsc->time_periods_count,
00219 sizeof(fsdp_time_period_t*));
00220 index = 0;
00221 for ( j = 0; j < dsc->time_periods_count; j++ ) {
00222 unsigned int h = 0;
00223 if ( sscanf(p,"t=%10lu %10lu",&wuint[0],&wuint[1]) != 2 ) {
00224
00225 dsc->time_periods_count = j;
00226 return FSDPE_INVALID_TIME;
00227 }
00228 dsc->time_periods[j] = calloc(1,sizeof(fsdp_time_period_t));
00229
00230
00231 if (wuint[0] != 0)
00232 wuint[0] -= NTP_EPOCH_OFFSET;
00233 if (wuint[1] != 0)
00234 wuint[1] -= NTP_EPOCH_OFFSET;
00235 dsc->time_periods[j]->start = wuint[0];
00236 dsc->time_periods[j]->stop = wuint[1];
00237 NEXT_LINE(p);
00238
00239
00240
00241
00242 p2 = p;
00243 while ( !strncmp(p2,"r=",2) ) {
00244 h++;
00245 NEXT_LINE(p2);
00246 }
00247 dsc->time_periods[j]->repeats_count = h;
00248 if ( h > 0 ) {
00249 unsigned int index2 = 0;
00250 dsc->time_periods[j]->repeats = calloc(h,sizeof(fsdp_repeat_t*));
00251 for ( h = 0; h < dsc->time_periods[j]->repeats_count; h++ ) {
00252
00253
00254
00255
00256
00257 if ( sscanf(p,"r=%10s %10s %"MLFLENS"[^\r\n]",
00258 fsdp_buf[0],fsdp_buf[1],longfsdp_buf) == 3 ) {
00259 fsdp_repeat_t *repeat;
00260 dsc->time_periods[j]->repeats[h] = calloc(1,sizeof(fsdp_repeat_t));
00261 repeat = dsc->time_periods[j]->repeats[h];
00262
00263 result = fsdp_repeat_time_to_uint(fsdp_buf[0],&(repeat->interval));
00264 if ( result == FSDPE_OK ) {
00265 result = fsdp_repeat_time_to_uint(fsdp_buf[1],&(repeat->duration));
00266 if ( result == FSDPE_OK ) {
00267 unsigned int k = 1;
00268 const char *i = longfsdp_buf;
00269 while ( NULL != (i = strchr(i,' ')) ) {
00270 k++;
00271 if ( NULL != i )
00272 i++;
00273 }
00274 repeat->offsets_count = k;
00275 repeat->offsets = calloc(k,sizeof(time_t));
00276 i = longfsdp_buf;
00277 for ( k = 0;
00278 (k < repeat->offsets_count) && (result == FSDPE_OK);
00279 k++ ) {
00280 result = fsdp_repeat_time_to_uint(i,&(repeat->offsets[k]));
00281 i = strchr(i,' ');
00282 if ( NULL != i)
00283 i++;
00284 }
00285 if ( k < repeat->offsets_count ) {
00286
00287 dsc->time_periods[j]->repeats_count = k;
00288 return FSDPE_INVALID_REPEAT;
00289 }
00290 }
00291 }
00292 if ( result != FSDPE_OK ) {
00293
00294 dsc->time_periods[j]->repeats_count = h;
00295 return FSDPE_INVALID_REPEAT;
00296 }
00297 NEXT_LINE(p);
00298 } else {
00299
00300 dsc->time_periods[j]->repeats_count = h;
00301 return FSDPE_INVALID_REPEAT;
00302 }
00303 index2++;
00304 }
00305 }
00306 }
00307
00308
00309
00310 if ( !strncmp(p,"z=",2) ) {
00311 if ( sscanf(p,"z=%"MLFLENS"[^\r\n]",longfsdp_buf) ) {
00312
00313 dsc->timezone_adj = strdup(longfsdp_buf);
00314 NEXT_LINE(p);
00315 } else {
00316 return FSDPE_INVALID_TIMEZONE;
00317 }
00318 }
00319
00320
00321
00322
00323 result = fsdp_parse_k(&p,&(dsc->k_encryption_method),
00324 &(dsc->k_encryption_content));
00325 if ( result != FSDPE_OK )
00326 return result;
00327
00328
00329
00330
00331
00332 while ( !strncmp(p,"a=",2) ) {
00333
00334
00335 if ( sscanf(p,"a=%9[^:\r\n]:%"MSFLENS"[^\r\n]",fsdp_buf[0],fsdp_buf[1]) == 2 ) {
00336
00337 if ( !strncmp(fsdp_buf[0],"cat",3) )
00338 dsc->a_str_attributes[FSDP_SESSION_STR_ATT_CATEGORY] =
00339 strdup(fsdp_buf[1]);
00340 else if ( !strncmp(fsdp_buf[0],"keywds",6) )
00341 dsc->a_str_attributes[FSDP_SESSION_STR_ATT_KEYWORDS] =
00342 strdup(fsdp_buf[1]);
00343 else if ( !strncmp(fsdp_buf[0],"tool",4) )
00344 dsc->a_str_attributes[FSDP_SESSION_STR_ATT_TOOL] =
00345 strdup(fsdp_buf[1]);
00346 else if ( !strncmp(fsdp_buf[0],"rtpmap",6) )
00347 fsdp_parse_rtpmap(&(dsc->a_rtpmaps),
00348 &(dsc->a_rtpmaps_count),fsdp_buf[1]);
00349 else if ( !strncmp(fsdp_buf[0],"type",4) ) {
00350 if ( !strncmp(fsdp_buf[1],"broadcast",9) )
00351 dsc->a_type = FSDP_SESSION_TYPE_BROADCAST;
00352 else if ( !strncmp(fsdp_buf[1],"meeting",7) )
00353 dsc->a_type = FSDP_SESSION_TYPE_MEETING;
00354 else if ( !strncmp(fsdp_buf[1],"moderated",9) )
00355 dsc->a_type = FSDP_SESSION_TYPE_MODERATED;
00356 else if ( !strncmp(fsdp_buf[1],"test",4) )
00357 dsc->a_type = FSDP_SESSION_TYPE_TEST;
00358 else if ( !strncmp(fsdp_buf[1],"H332",4) )
00359 dsc->a_type = FSDP_SESSION_TYPE_H332;
00360 else
00361 return FSDPE_INVALID_SESSION_TYPE;
00362 } else if ( !strncmp(fsdp_buf[0],"charset",7) )
00363 dsc->a_str_attributes[FSDP_SESSION_STR_ATT_CHARSET] =
00364 strdup(fsdp_buf[1]);
00365 else if ( !strncmp(fsdp_buf[0],"sdplang",7) ) {
00366 if ( NULL == dsc->a_sdplangs ) {
00367 dsc->a_sdplangs_count = 0;
00368 dsc->a_sdplangs = calloc(SDPLANGS_MAX_COUNT,sizeof(char*));
00369 }
00370 if ( dsc->a_sdplangs_count < SDPLANGS_MAX_COUNT ) {
00371 dsc->a_sdplangs[dsc->a_sdplangs_count] = strdup(fsdp_buf[1]);
00372 dsc->a_sdplangs_count++;
00373 }
00374 } else if ( !strncmp(fsdp_buf[0],"lang",4) ) {
00375 if ( NULL == dsc->a_langs ) {
00376 dsc->a_langs_count = 0;
00377 dsc->a_langs = calloc(SDPLANGS_MAX_COUNT,sizeof(char*));
00378 }
00379 if ( dsc->a_langs_count < SDPLANGS_MAX_COUNT ) {
00380 dsc->a_langs[dsc->a_langs_count] = strdup(fsdp_buf[1]);
00381 dsc->a_langs_count++;
00382 }
00383 } else {
00384
00385 *longfsdp_buf = '\0';
00386 strncat(longfsdp_buf,fsdp_buf[0],MAXLONGFIELDLEN);
00387 strncat(longfsdp_buf,":",MAXLONGFIELDLEN);
00388 strncat(longfsdp_buf,fsdp_buf[1],MAXLONGFIELDLEN);
00389 if ( NULL == dsc->unidentified_attributes ) {
00390 dsc->unidentified_attributes_count = 0;
00391 dsc->unidentified_attributes =
00392 calloc(UNIDENTIFIED_ATTRIBUTES_MAX_COUNT,sizeof(char*));
00393 }
00394 if ( dsc->unidentified_attributes_count <
00395 UNIDENTIFIED_ATTRIBUTES_MAX_COUNT ) {
00396 dsc->unidentified_attributes
00397 [dsc->unidentified_attributes_count] = strdup(longfsdp_buf);
00398 dsc->unidentified_attributes_count++;
00399 }
00400 }
00401 NEXT_LINE(p);
00402 } else if ( sscanf(p,"a=%20s",fsdp_buf[0]) == 1 ) {
00403
00404 if ( !strncmp(fsdp_buf[0],"recvonly",8) )
00405 dsc->a_sendrecv_mode = FSDP_SENDRECV_RECVONLY;
00406 else if ( !strncmp(fsdp_buf[0],"sendonly",8) )
00407 dsc->a_sendrecv_mode = FSDP_SENDRECV_SENDONLY;
00408 else if ( !strncmp(fsdp_buf[0],"inactive",8) )
00409 dsc->a_sendrecv_mode = FSDP_SENDRECV_INACTIVE;
00410 else if ( !strncmp(fsdp_buf[0],"sendrecv",8) )
00411 dsc->a_sendrecv_mode = FSDP_SENDRECV_SENDRECV;
00412 else {
00413
00414 *longfsdp_buf = '\0';
00415 strncat(longfsdp_buf,fsdp_buf[0],MAXLONGFIELDLEN);
00416 if ( NULL == dsc->unidentified_attributes ) {
00417 dsc->unidentified_attributes_count = 0;
00418 dsc->unidentified_attributes =
00419 calloc(UNIDENTIFIED_ATTRIBUTES_MAX_COUNT,sizeof(char*));
00420 }
00421 if ( dsc->unidentified_attributes_count <
00422 UNIDENTIFIED_ATTRIBUTES_MAX_COUNT ) {
00423 dsc->unidentified_attributes
00424 [dsc->unidentified_attributes_count] = strdup(longfsdp_buf);
00425 dsc->unidentified_attributes_count++;
00426 }
00427 }
00428 NEXT_LINE(p);
00429 } else
00430 return FSDPE_INVALID_ATTRIBUTE;
00431 }
00432
00433
00434
00435
00436 p2 = p;
00437 j = 0;
00438 while ( (*p2 != '\0') && !strncmp(p2,"m=",2) ) {
00439 char c;
00440 j++;
00441 NEXT_LINE(p2);
00442 while ( sscanf(p2,"%c=",&c) == 1 ) {
00443 if ( c == 'i' || c == 'c' || c == 'b' || c == 'k' || c == 'a' ) {
00444 NEXT_LINE(p2);
00445 } else if ( c == 'm' ) {
00446 break;
00447 } else {
00448 return FSDPE_INVALID_LINE;
00449 }
00450 }
00451 }
00452 dsc->media_announcements_count = j;
00453 if ( dsc->media_announcements_count == 0 ) {
00454 ;
00455
00456 } else {
00457 dsc->media_announcements = calloc(j,sizeof(fsdp_media_announcement_t*));
00458 for ( j = 0; j < dsc->media_announcements_count; j++ ) {
00459 fsdp_media_announcement_t *media = NULL;
00460
00461
00462
00463 if ( sscanf(p,"m=%11s %8s %7s %"MLFLENS"[^\r\n]",
00464 fsdp_buf[0],fsdp_buf[1],fsdp_buf[2],longfsdp_buf) != 4 ) {
00465 return FSDPE_INVALID_MEDIA;
00466 } else {
00467 dsc->media_announcements[j] =
00468 calloc(1,sizeof(fsdp_media_announcement_t));
00469 media = dsc->media_announcements[j];
00470 if ( !strncmp(fsdp_buf[0],"audio",5) )
00471 media->media_type = FSDP_MEDIA_AUDIO;
00472 else if ( !strncmp(fsdp_buf[0],"video",5) )
00473 media->media_type = FSDP_MEDIA_VIDEO;
00474 else if ( !strncmp(fsdp_buf[0],"text",4) )
00475 media->media_type = FSDP_MEDIA_TEXT;
00476 else if ( !strncmp(fsdp_buf[0],"application",11) )
00477 media->media_type = FSDP_MEDIA_APPLICATION;
00478 else if ( !strncmp(fsdp_buf[0],"data",4) )
00479 media->media_type = FSDP_MEDIA_DATA;
00480 else if ( !strncmp(fsdp_buf[0],"control",7) )
00481 media->media_type = FSDP_MEDIA_CONTROL;
00482 else
00483 return FSDPE_UNKNOWN_MEDIA_TYPE;
00484 {
00485 char *slash;
00486 if ( (slash = strchr(fsdp_buf[1],'/')) ) {
00487 *slash = '\0';
00488 slash++;
00489 media->port = strtol(fsdp_buf[1],NULL,10);
00490 media->port_count = strtol(slash,NULL,10);
00491 } else {
00492 media->port = strtol(fsdp_buf[1],NULL,10);
00493 media->port_count = 0;
00494 }
00495 }
00496 if ( !strncmp(fsdp_buf[2],"RTP/AVP",7) )
00497 media->transport = FSDP_TP_RTP_AVP;
00498 else if ( !strncmp(fsdp_buf[2],"udp",3) )
00499 media->transport = FSDP_TP_UDP;
00500 else if ( !strncmp(fsdp_buf[2],"TCP",3) )
00501 media->transport = FSDP_TP_TCP;
00502 else if ( !strncmp(fsdp_buf[2],"UDPTL",5) )
00503 media->transport = FSDP_TP_UDPTL;
00504 else if ( !strncmp(fsdp_buf[2],"vat",3) )
00505 media->transport = FSDP_TP_VAT;
00506 else if ( !strncmp(fsdp_buf[2],"rtp",3) )
00507 media->transport = FSDP_TP_OLD_RTP;
00508 else
00509 return FSDPE_UNKNOWN_MEDIA_TRANSPORT;
00510 {
00511 unsigned int k = 0;
00512 char *s = longfsdp_buf;
00513 while ( NULL != ( s = strchr(s,' ')) ) {
00514 k++;
00515 if ( NULL != s )
00516 s++;
00517 }
00518 k++;
00519 media->formats_count = k;
00520 media->formats = calloc(k,sizeof(char*));
00521 s = longfsdp_buf;
00522 for ( k = 0; k < media->formats_count; k++ ) {
00523 char *space = strchr(s,' ');
00524 if ( NULL != space )
00525 *space = '\0';
00526 media->formats[k] = strdup(s);
00527 s = space + 1;
00528 }
00529 }
00530 NEXT_LINE(p);
00531 }
00532
00533
00534
00535 if ( !strncmp(p,"i=",2) && sscanf(p,"i=%"MLFLENS"[^\r\n]",longfsdp_buf) ) {
00536 media->i_title = strdup(longfsdp_buf);
00537 NEXT_LINE(p);
00538 } else {
00539
00540 }
00541
00542
00543
00544
00545 result = fsdp_parse_c(&p,&(media->c_network_type),
00546 &(media->c_address_type),&(media->c_address));
00547 if ( result != FSDPE_OK )
00548 return result;
00549
00550
00551
00552 result = fsdp_parse_b(&p,&(media->bw_modifiers),
00553 &(media->bw_modifiers_count));
00554 if ( FSDPE_OK != result )
00555 return result;
00556
00557
00558
00559
00560 result = fsdp_parse_k(&p,&(media->k_encryption_method),
00561 &(media->k_encryption_content));
00562 if ( result != FSDPE_OK )
00563 return result;
00564
00565
00566
00567
00568
00569
00570 while ( !strncmp(p,"a=",2) ) {
00571 if ( sscanf(p,"a=%9[^:\r\n]:%"MLFLENS"[^\r\n]",fsdp_buf[0],longfsdp_buf)
00572 == 2 ) {
00573
00574 if ( !strncmp(fsdp_buf[0],"ptime",5) )
00575 media->a_ptime = strtoul(longfsdp_buf,NULL,10);
00576 else if ( !strncmp(fsdp_buf[0],"maxptime",8) )
00577 media->a_maxptime = strtoul(longfsdp_buf,NULL,10);
00578 else if ( !strncmp(fsdp_buf[0],"rtpmap",6) )
00579 fsdp_parse_rtpmap(&(media->a_rtpmaps),
00580 &(media->a_rtpmaps_count),longfsdp_buf);
00581 else if ( !strncmp(fsdp_buf[0],"orient",6) ) {
00582 if ( !strncmp(longfsdp_buf,"portrait",8) )
00583 media->a_orient = FSDP_ORIENT_PORTRAIT;
00584 else if ( !strncmp(longfsdp_buf,"landscape",9) )
00585 media->a_orient = FSDP_ORIENT_LANDSCAPE;
00586 else if ( !strncmp(longfsdp_buf,"seascape",9) )
00587 media->a_orient = FSDP_ORIENT_SEASCAPE;
00588 } else if ( !strncmp(fsdp_buf[0],"sdplang",7) ) {
00589 if ( NULL == dsc->a_sdplangs ) {
00590 media->a_sdplangs_count = 0;
00591 media->a_sdplangs =
00592 calloc(SDPLANGS_MAX_COUNT,sizeof(char*));
00593 }
00594 if ( media->a_sdplangs_count < SDPLANGS_MAX_COUNT ) {
00595 media->a_sdplangs[dsc->a_sdplangs_count] = strdup(longfsdp_buf);
00596 media->a_sdplangs_count++;
00597 }
00598 } else if ( !strncmp(fsdp_buf[0],"lang",4) ) {
00599 if ( NULL == dsc->a_langs ) {
00600 media->a_langs_count = 0;
00601 media->a_langs = calloc(SDPLANGS_MAX_COUNT,sizeof(char*));
00602 }
00603 if ( media->a_langs_count < SDPLANGS_MAX_COUNT ) {
00604 media->a_langs[dsc->a_langs_count] = strdup(longfsdp_buf);
00605 media->a_langs_count++;
00606 }
00607 } else if ( !strncmp(fsdp_buf[0],"framerate",9) )
00608 media->a_framerate = strtof(longfsdp_buf,NULL);
00609 else if ( !strncmp(fsdp_buf[0],"fmtp",4) ) {
00610 if ( NULL == media->a_fmtps ) {
00611 media->a_fmtps_count = 0;
00612 media->a_fmtps = calloc(SDPLANGS_MAX_COUNT,sizeof(char*));
00613 }
00614 if ( media->a_fmtps_count < SDPLANGS_MAX_COUNT ) {
00615 media->a_fmtps[media->a_fmtps_count] = strdup(longfsdp_buf);
00616 media->a_fmtps_count++;
00617 }
00618 } else if ( !strncmp(fsdp_buf[0],"rtcp",4) ) {
00619 int opts = 0;
00620
00621 opts = sscanf(longfsdp_buf,"%lu %2s %3s %"MSFLENS"s",
00622 &wuint[0],fsdp_buf[0],fsdp_buf[1],fsdp_buf[2]);
00623 if ( opts >= 1 ) {
00624 media->a_rtcp_port = wuint[0];
00625 if ( opts >= 2 ) {
00626 if ( !strncmp(fsdp_buf[0],"IN",2) ) {
00627 media->a_rtcp_network_type = FSDP_NETWORK_TYPE_INET;
00628 }
00629
00630 if ( opts >= 3 ) {
00631 if ( !strncmp(fsdp_buf[1],"IP4",3) )
00632 media->a_rtcp_address_type = FSDP_ADDRESS_TYPE_IPV4;
00633 else if ( !strncmp(fsdp_buf[1],"IP6",3) )
00634 media->a_rtcp_address_type = FSDP_ADDRESS_TYPE_IPV6;
00635 else
00636 return FSDPE_INVALID_CONNECTION_NETTYPE;
00637
00638 if ( opts >= 4)
00639 media->a_rtcp_address = strdup(fsdp_buf[2]);
00640 }
00641 }
00642 }
00643 } else {
00644
00645 *fsdp_buf[1] = '\0';
00646 strncat(fsdp_buf[1],fsdp_buf[0],MAXLONGFIELDLEN);
00647 strncat(fsdp_buf[1],":",MAXLONGFIELDLEN);
00648 strncat(fsdp_buf[1],longfsdp_buf,MAXLONGFIELDLEN);
00649 if ( NULL == media->unidentified_attributes ) {
00650 media->unidentified_attributes_count = 0;
00651 media->unidentified_attributes =
00652 calloc(UNIDENTIFIED_ATTRIBUTES_MAX_COUNT,sizeof(char*));
00653 }
00654 if ( media->unidentified_attributes_count <
00655 UNIDENTIFIED_ATTRIBUTES_MAX_COUNT ) {
00656 media->unidentified_attributes
00657 [media->unidentified_attributes_count] = strdup(fsdp_buf[1]);
00658 media->unidentified_attributes_count++;
00659 }
00660 }
00661 NEXT_LINE(p);
00662 } else if ( sscanf(p,"a=%8s",fsdp_buf[0]) == 1 ) {
00663
00664 if ( !strncmp(fsdp_buf[0],"recvonly",8) )
00665 media->a_sendrecv_mode = FSDP_SENDRECV_RECVONLY;
00666 else if ( !strncmp(fsdp_buf[0],"sendonly",8) )
00667 media->a_sendrecv_mode = FSDP_SENDRECV_SENDONLY;
00668 else if ( !strncmp(fsdp_buf[0],"inactive",8) )
00669 media->a_sendrecv_mode = FSDP_SENDRECV_INACTIVE;
00670 else if ( !strncmp(fsdp_buf[0],"sendrecv",8) )
00671 media->a_sendrecv_mode = FSDP_SENDRECV_SENDRECV;
00672 else {
00673
00674 *longfsdp_buf = '\0';
00675 strncat(longfsdp_buf,fsdp_buf[0],MAXLONGFIELDLEN);
00676 if ( NULL == media->unidentified_attributes ) {
00677 media->unidentified_attributes_count = 0;
00678 media->unidentified_attributes =
00679 calloc(UNIDENTIFIED_ATTRIBUTES_MAX_COUNT,sizeof(char*));
00680 }
00681 if ( media->unidentified_attributes_count <
00682 UNIDENTIFIED_ATTRIBUTES_MAX_COUNT ) {
00683 media->unidentified_attributes
00684 [media->unidentified_attributes_count] = strdup(longfsdp_buf);
00685 media->unidentified_attributes_count++;
00686 }
00687 }
00688 NEXT_LINE(p);
00689 } else
00690 return FSDPE_INVALID_ATTRIBUTE;
00691 }
00692 }
00693 }
00694
00695
00696
00697 if ( NULL == dsc->c_address.address ) {
00698 unsigned int c;
00699 for ( c = 0; c < dsc->media_announcements_count; c++)
00700 if ( NULL == dsc->media_announcements[c]->c_address.address )
00701 return FSDPE_MISSING_CONNECTION_INFO;
00702 }
00703
00704
00705 if ( *p == '\0' )
00706 return FSDPE_OK;
00707 else
00708 return FSDPE_OVERFILLED;
00709 }
00710
00711 static fsdp_error_t
00712 fsdp_parse_c(const char **p, fsdp_network_type_t *ntype,
00713 fsdp_address_type_t *atype, fsdp_connection_address_t *address)
00714 {
00715 const unsigned int TEMPCHARS = 3;
00716 char fsdp_buf[TEMPCHARS][MAXSHORTFIELDLEN];
00717
00718 if ( !strncmp(*p,"c=",2) ) {
00719 if ( sscanf(*p,"c=%2s %3s %"MSFLENS"s",fsdp_buf[0],fsdp_buf[1],fsdp_buf[2]) ) {
00720 if ( !strncmp(fsdp_buf[0],"IN",2) ) {
00721 *ntype = FSDP_NETWORK_TYPE_INET;
00722 if ( !strncmp(fsdp_buf[1],"IP4",3) )
00723 *atype = FSDP_ADDRESS_TYPE_IPV4;
00724 else if ( !strncmp(fsdp_buf[1],"IP6",3) )
00725 *atype = FSDP_ADDRESS_TYPE_IPV6;
00726 else
00727 return FSDPE_INVALID_CONNECTION_NETTYPE;
00728 } else {
00729 return FSDPE_INVALID_CONNECTION_ADDRTYPE;
00730 }
00731 {
00732 char *slash = strchr(fsdp_buf[2],'/');
00733 if ( NULL == slash ) {
00734 address->address = strdup(fsdp_buf[2]);
00735 address->address_ttl = 0;
00736 address->address_count = 0;
00737 } else {
00738
00739 char *slash2;
00740 *slash = '\0';
00741 slash++;
00742 address->address = strdup(fsdp_buf[2]);
00743 slash2 = strchr(slash + 1,'/');
00744 if ( NULL == slash2 ) {
00745 address->address_ttl = strtol(slash,NULL,10);
00746 address->address_count = 0;
00747 } else {
00748 *slash2 = '\0';
00749 slash2++;
00750 address->address_ttl = strtol(slash,NULL,10);
00751 address->address_count = strtol(slash2,NULL,10);
00752 }
00753 }
00754 }
00755 NEXT_LINE(*p);
00756 } else {
00757 return FSDPE_INVALID_CONNECTION;
00758 }
00759 }
00760 return FSDPE_OK;
00761 }
00762
00763 static fsdp_error_t
00764 fsdp_parse_b(const char **p, fsdp_bw_modifier_t **bw_modifiers,
00765 unsigned int *bw_modifiers_count)
00766 {
00767 char fsdp_buf[MAXSHORTFIELDLEN];
00768 unsigned long int wuint;
00769 unsigned int i = 0;
00770 char *lp = (char*)*p;
00771
00772
00773 while ( !strncmp(lp,"b=",2) ) {
00774 NEXT_LINE(lp);
00775 i++;
00776 }
00777 *bw_modifiers = calloc(i,sizeof(fsdp_bw_modifier_t));
00778 *bw_modifiers_count = i;
00779
00780 while ( i > 0 ) {
00781 unsigned int index = *bw_modifiers_count - i;
00782 if ( 2 == sscanf(*p,"b=%20[^:\r\n]:%lu",fsdp_buf,&wuint) ) {
00783 if ( !strncmp(fsdp_buf,"CT",2) )
00784 (*bw_modifiers)[index].b_mod_type = FSDP_BW_MOD_TYPE_CONFERENCE_TOTAL;
00785 else if ( !strncmp(fsdp_buf,"AS",2) )
00786 (*bw_modifiers)[index].b_mod_type = FSDP_BW_MOD_TYPE_APPLICATION_SPECIFIC;
00787 else if ( !strncmp(fsdp_buf,"RS",2) )
00788 (*bw_modifiers)[index].b_mod_type = FSDP_BW_MOD_TYPE_RTCP_SENDERS;
00789 else if ( !strncmp(fsdp_buf,"RR",2) )
00790 (*bw_modifiers)[index].b_mod_type = FSDP_BW_MOD_TYPE_RTCP_RECEIVERS;
00791 else {
00792 (*bw_modifiers)[index].b_mod_type = FSDP_BW_MOD_TYPE_UNKNOWN;
00793 (*bw_modifiers)[index].b_unknown_bw_modt = (char *)strdup(fsdp_buf);
00794 }
00795 (*bw_modifiers)[index].b_value = wuint;
00796 NEXT_LINE(*p);
00797 } else {
00798 *bw_modifiers_count -= i;
00799 return FSDPE_INVALID_BANDWIDTH;
00800 }
00801 i--;
00802 }
00803 return FSDPE_OK;
00804 }
00805
00806 static fsdp_error_t
00807 fsdp_parse_k(const char **p, fsdp_encryption_method_t *method, char **content)
00808 {
00809 char fsdp_buf[MAXSHORTFIELDLEN];
00810 char longfsdp_buf[MAXLONGFIELDLEN];
00811
00812 if ( !strncmp(*p,"k=",2) ) {
00813 if ( sscanf(*p,"k=prompt") ) {
00814 *method = FSDP_ENCRYPTION_METHOD_PROMPT;
00815 *content = NULL;
00816 NEXT_LINE(*p);
00817 } else {
00818 if ( sscanf(*p,"k=%6[^:\r\n]:%"MLFLENS"s",fsdp_buf,longfsdp_buf) ) {
00819 if ( !strncmp(fsdp_buf,"clear",5) )
00820 *method = FSDP_ENCRYPTION_METHOD_CLEAR;
00821 else if ( !strncmp(fsdp_buf,"base64",6) )
00822 *method = FSDP_ENCRYPTION_METHOD_BASE64;
00823 else if ( !strncmp(fsdp_buf,"uri",3) )
00824 *method = FSDP_ENCRYPTION_METHOD_URI;
00825 else
00826 return FSDPE_INVALID_ENCRYPTION_METHOD;
00827 *content = strdup(longfsdp_buf);
00828 NEXT_LINE(*p);
00829 }
00830 }
00831 }
00832 return FSDPE_OK;
00833 }
00834
00835 static fsdp_error_t
00836 fsdp_parse_rtpmap(fsdp_rtpmap_t ***rtpmap, unsigned int *counter,
00837 const char *value)
00838 {
00839 fsdp_error_t result = FSDPE_OK;
00840
00841 if ( 0 == *counter ) {
00842 *counter = 0;
00843 *rtpmap = calloc(MEDIA_RTPMAPS_MAX_COUNT,sizeof(fsdp_rtpmap_t*));
00844 }
00845 if ( *counter < MEDIA_RTPMAPS_MAX_COUNT ) {
00846 unsigned int c = *counter;
00847 fsdp_rtpmap_t **map = *rtpmap;
00848 char fsdp_buf[MAXSHORTFIELDLEN];
00849 char longfsdp_buf[MAXLONGFIELDLEN];
00850 map[c] = calloc(1,sizeof(fsdp_rtpmap_t));
00851
00852
00853
00854 if ( 2 == sscanf(value,"%s %s",fsdp_buf,longfsdp_buf) ) {
00855 char *slash1;
00856 map[c]->pt = strdup(fsdp_buf);
00857
00858 slash1 = strchr(longfsdp_buf,'/');
00859 if ( NULL == slash1 ) {
00860 result = FSDPE_INVALID_ATTRIBUTE_RTPMAP;
00861 } else {
00862 char *slash2;
00863 *slash1 = '\0';
00864 slash1++;
00865 map[c]->encoding_name = strdup(longfsdp_buf);
00866 slash2 = strchr(slash1,'/');
00867 if ( NULL != slash2 ) {
00868 *slash2 = '\0';
00869 slash2++;
00870 map[c]->parameters = strdup(slash2);
00871 }
00872 map[c]->clock_rate = strtol(slash1,NULL,10);
00873 }
00874 (*counter)++;
00875 }
00876 }
00877 return result;
00878 }
00879
00880 static fsdp_error_t
00881 fsdp_repeat_time_to_uint(const char *time, unsigned long int *seconds)
00882 {
00883 const unsigned long SECONDS_PER_DAY = 86400;
00884 const unsigned long SECONDS_PER_HOUR = 3600;
00885 const unsigned long SECONDS_PER_MINUTE = 60;
00886 char c;
00887 unsigned long int wuint;
00888
00889 if ( sscanf(time,"%lu%c",&wuint,&c) == 2 ) {
00890
00891 switch(c) {
00892 case 'd':
00893 *seconds = wuint * SECONDS_PER_DAY;
00894 break;
00895 case 'h':
00896 *seconds = wuint * SECONDS_PER_HOUR;
00897 break;
00898 case 'm':
00899 *seconds = wuint * SECONDS_PER_MINUTE;
00900 break;
00901 case 's':
00902 *seconds = wuint;
00903 break;
00904 default:
00905 return FSDPE_INVALID_REPEAT;
00906 break;
00907 }
00908 } else if ( sscanf(time,"%lu",&wuint) == 1 ) {
00909
00910 *seconds = wuint;
00911 } else {
00912 return FSDPE_INVALID_REPEAT;
00913 }
00914 return FSDPE_OK;
00915 }
00916
00917 unsigned int
00918 fsdp_get_version(const fsdp_description_t *dsc)
00919 {
00920 if ( NULL == dsc)
00921 return 0;
00922 return dsc->version;
00923 }
00924
00925 const char *
00926 fsdp_get_owner_username(const fsdp_description_t *dsc)
00927 {
00928 if ( NULL == dsc)
00929 return NULL;
00930 return dsc->o_username;
00931 }
00932
00933 const char *
00934 fsdp_get_session_id(const fsdp_description_t *dsc)
00935 {
00936 if ( NULL == dsc)
00937 return NULL;
00938 return dsc->o_session_id;
00939 }
00940
00941 const char *
00942 fsdp_get_announcement_version(const fsdp_description_t *dsc)
00943 {
00944 if ( NULL == dsc)
00945 return NULL;
00946 return dsc->o_announcement_version;
00947 }
00948
00949 fsdp_network_type_t
00950 fsdp_get_owner_network_type(const fsdp_description_t *dsc)
00951 {
00952 if ( NULL == dsc)
00953 return FSDP_NETWORK_TYPE_UNDEFINED;
00954 return dsc->o_network_type;
00955 }
00956
00957 fsdp_address_type_t
00958 fsdp_get_owner_address_type(const fsdp_description_t *dsc)
00959 {
00960 if ( NULL == dsc)
00961 return FSDP_ADDRESS_TYPE_UNDEFINED;
00962 return dsc->o_address_type;
00963 }
00964
00965 const char *
00966 fsdp_get_owner_address(const fsdp_description_t *dsc)
00967 {
00968 if ( NULL == dsc)
00969 return NULL;
00970 return dsc->o_address;
00971 }
00972
00973 const char *
00974 fsdp_get_name(const fsdp_description_t *dsc)
00975 {
00976 if ( NULL == dsc)
00977 return NULL;
00978 return dsc->s_name;
00979 }
00980
00981 const char *
00982 fsdp_get_information(const fsdp_description_t *dsc)
00983 {
00984 if ( NULL == dsc)
00985 return NULL;
00986 return dsc->i_information;
00987 }
00988
00989 const char *
00990 fsdp_get_uri(const fsdp_description_t *dsc)
00991 {
00992 if ( NULL == dsc)
00993 return NULL;
00994 return dsc->u_uri;
00995 }
00996
00997 unsigned int
00998 fsdp_get_emails_count(const fsdp_description_t *dsc)
00999 {
01000 if ( NULL == dsc)
01001 return 0;
01002 return dsc->emails_count;
01003 }
01004
01005 const char *
01006 fsdp_get_email(const fsdp_description_t *dsc, unsigned int index)
01007 {
01008 if ( (NULL == dsc) || (index >= dsc->emails_count) )
01009 return NULL;
01010 return dsc->emails[index];
01011 }
01012
01013 unsigned int
01014 fsdp_get_phones_count(const fsdp_description_t *dsc)
01015 {
01016 if ( NULL == dsc)
01017 return 0;
01018 return dsc->phones_count;
01019 }
01020
01021 const char *
01022 fsdp_get_phone(const fsdp_description_t *dsc, unsigned int index)
01023 {
01024 if ( (NULL == dsc ) || (index >= dsc->phones_count) )
01025 return NULL;
01026 return dsc->phones[index];
01027 }
01028
01029 fsdp_network_type_t
01030 fsdp_get_global_conn_network_type(const fsdp_description_t *dsc)
01031 {
01032 if ( NULL == dsc)
01033 return FSDP_NETWORK_TYPE_UNDEFINED;
01034 return dsc->c_network_type;
01035 }
01036
01037 fsdp_address_type_t
01038 fsdp_get_global_conn_address_type(const fsdp_description_t *dsc)
01039 {
01040 if ( NULL == dsc)
01041 return FSDP_ADDRESS_TYPE_UNDEFINED;
01042 return dsc->c_address_type;
01043 }
01044
01045 const char *
01046 fsdp_get_global_conn_address(const fsdp_description_t *dsc)
01047 {
01048 if ( NULL == dsc)
01049 return NULL;
01050 return dsc->c_address.address;
01051 }
01052
01053 unsigned int
01054 fsdp_get_global_conn_address_ttl(const fsdp_description_t *dsc)
01055 {
01056 if ( NULL == dsc)
01057 return 0;
01058 return dsc->c_address.address_ttl;
01059 }
01060
01061 unsigned int
01062 fsdp_get_global_conn_address_count(const fsdp_description_t *dsc)
01063 {
01064 if ( NULL == dsc)
01065 return 0;
01066 return dsc->c_address.address_count;
01067 }
01068
01069 unsigned int
01070 fsdp_get_bw_modifier_count(const fsdp_description_t *dsc)
01071 {
01072 if ( (NULL == dsc) )
01073 return 0;
01074 return dsc->bw_modifiers_count;
01075 }
01076
01077 fsdp_bw_modifier_type_t
01078 fsdp_get_bw_modifier_type(const fsdp_description_t *dsc, unsigned int index)
01079 {
01080 if ( (NULL == dsc) || (index >= dsc->bw_modifiers_count) )
01081 return FSDP_BW_MOD_TYPE_UNDEFINED;
01082 return dsc->bw_modifiers[index].b_mod_type;
01083 }
01084
01085 const char *
01086 fsdp_get_bw_modifier_type_unknown(const fsdp_description_t *dsc,
01087 unsigned int index)
01088 {
01089 if ( (NULL == dsc) || (index >= dsc->bw_modifiers_count) ||
01090 (dsc->bw_modifiers[index].b_mod_type != FSDP_BW_MOD_TYPE_UNKNOWN) )
01091 return NULL;
01092 return dsc->bw_modifiers[index].b_unknown_bw_modt;
01093 }
01094
01095 unsigned long int
01096 fsdp_get_bw_value(const fsdp_description_t *dsc, unsigned int index)
01097 {
01098 if ( (NULL == dsc) || (index >= dsc->bw_modifiers_count) )
01099 return 0;
01100 return dsc->bw_modifiers[index].b_value;
01101 }
01102
01103 time_t
01104 fsdp_get_period_start(const fsdp_description_t *dsc, unsigned int index)
01105 {
01106 if ( (NULL == dsc) || (index >= dsc->time_periods_count) )
01107 return 0;
01108 return dsc->time_periods[index]->start;
01109 }
01110
01111 time_t
01112 fsdp_get_period_stop(const fsdp_description_t *dsc, unsigned int index)
01113 {
01114 if ( (NULL == dsc) || (index >= dsc->time_periods_count) )
01115 return 0;
01116 return dsc->time_periods[index]->stop;
01117 }
01118
01119 unsigned int
01120 fsdp_get_period_repeats_count(const fsdp_description_t *dsc,
01121 unsigned int index)
01122 {
01123 if ( (NULL == dsc) || (index >= dsc->time_periods_count) )
01124 return 0;
01125 return dsc->time_periods[index]->repeats_count;
01126 }
01127
01128 unsigned long int
01129 fsdp_get_period_repeat_interval(const fsdp_description_t *dsc,
01130 unsigned int index, unsigned int rindex)
01131 {
01132 if ( (NULL == dsc) || (index >= dsc->time_periods_count) )
01133 return 0;
01134 return dsc->time_periods[index]->repeats[rindex]->interval;
01135 }
01136
01137 unsigned long int
01138 fsdp_get_period_repeat_duration(const fsdp_description_t *dsc,
01139 unsigned int index, unsigned int rindex)
01140 {
01141 if ( (NULL == dsc) || (index >= dsc->time_periods_count) )
01142 return 0;
01143 return dsc->time_periods[index]->repeats[rindex]->duration;
01144 }
01145
01146 const unsigned long int *
01147 fsdp_get_period_repeat_offsets(const fsdp_description_t *dsc,
01148 unsigned int index, unsigned int rindex)
01149 {
01150 if ( (NULL == dsc) || (index >= dsc->time_periods_count) )
01151 return NULL;
01152 return dsc->time_periods[index]->repeats[rindex]->offsets;
01153 }
01154
01155 const char *
01156 fsdp_get_timezone_adj(const fsdp_description_t *dsc)
01157 {
01158 if ( NULL == dsc )
01159 return NULL;
01160 return dsc->timezone_adj;
01161 }
01162
01163 unsigned int
01164 fsdp_get_unidentified_attribute_count(const fsdp_description_t *dsc)
01165 {
01166 if ( NULL == dsc )
01167 return 0;
01168 return dsc->unidentified_attributes_count;
01169 }
01170
01171 const char *
01172 fsdp_get_unidentified_attribute(const fsdp_description_t *dsc,
01173 unsigned int index)
01174 {
01175 if ( NULL == dsc || (index < dsc->unidentified_attributes_count) )
01176 return NULL;
01177 return dsc->unidentified_attributes[index];
01178 }
01179
01180 fsdp_encryption_method_t
01181 fsdp_get_encryption_method(const fsdp_description_t *dsc)
01182 {
01183 if ( NULL == dsc )
01184 return FSDP_ENCRYPTION_METHOD_UNDEFINED;
01185 return dsc->k_encryption_method;
01186 }
01187
01188 const char *
01189 fsdp_get_encryption_content(const fsdp_description_t *dsc)
01190 {
01191 if ( (NULL == dsc) ||
01192 (dsc->k_encryption_method == FSDP_ENCRYPTION_METHOD_UNDEFINED) )
01193 return NULL;
01194 return dsc->k_encryption_content;
01195 }
01196
01197 unsigned int
01198 fsdp_get_rtpmap_count(const fsdp_description_t *dsc)
01199 {
01200 if ( NULL == dsc)
01201 return 0;
01202 return dsc->a_rtpmaps_count;
01203 }
01204
01205 const char *
01206 fsdp_get_rtpmap_payload_type(const fsdp_description_t *dsc, unsigned int index)
01207 {
01208 if ( (NULL == dsc) || (index >= dsc->a_rtpmaps_count) )
01209 return NULL;
01210 return dsc->a_rtpmaps[index]->pt;
01211 }
01212
01213 const char *
01214 fsdp_get_rtpmap_encoding_name(const fsdp_description_t *dsc,
01215 unsigned int index)
01216 {
01217 if ( (NULL == dsc) || (index >= dsc->a_rtpmaps_count) )
01218 return NULL;
01219 return dsc->a_rtpmaps[index]->encoding_name;
01220 }
01221
01222 unsigned int
01223 fsdp_get_rtpmap_clock_rate(const fsdp_description_t *dsc, unsigned int index)
01224 {
01225 if ( (NULL == dsc) || (index >= dsc->a_rtpmaps_count) )
01226 return 0;
01227 return dsc->a_rtpmaps[index]->clock_rate;
01228 }
01229
01230 const char *
01231 fsdp_get_rtpmap_encoding_parameters(const fsdp_description_t *dsc,
01232 unsigned int index)
01233 {
01234 if ( (NULL == dsc) || (index >= dsc->a_rtpmaps_count) )
01235 return NULL;
01236 return dsc->a_rtpmaps[index]->parameters;
01237 }
01238
01239 const char *
01240 fsdp_get_str_att(const fsdp_description_t *dsc, fsdp_session_str_att_t att)
01241 {
01242 char *result;
01243 if ( NULL == dsc )
01244 return NULL;
01245 if ( att <= FSDP_LAST_SESSION_STR_ATT )
01246 result = dsc->a_str_attributes[att];
01247 else
01248 result = NULL;
01249 return result;
01250 }
01251
01252 unsigned int
01253 fsdp_get_sdplang_count(const fsdp_description_t *dsc)
01254 {
01255 if ( NULL == dsc )
01256 return 0;
01257 return dsc->a_sdplangs_count;
01258 }
01259
01260 const char *
01261 fsdp_get_sdplang(const fsdp_description_t *dsc, unsigned int index)
01262 {
01263 if ( (NULL == dsc) || (index >= dsc->a_sdplangs_count) )
01264 return NULL;
01265 return dsc->a_sdplangs[index];
01266 }
01267
01268 unsigned int
01269 fsdp_get_lang_count(const fsdp_description_t *dsc)
01270 {
01271 if ( NULL == dsc )
01272 return 0;
01273 return dsc->a_langs_count;
01274 }
01275
01276 const char *
01277 fsdp_get_lang(const fsdp_description_t *dsc, unsigned int index)
01278 {
01279 if ( (NULL == dsc) || (index >= dsc->a_langs_count) )
01280 return NULL;
01281 return dsc->a_langs[index];
01282 }
01283
01284 fsdp_sendrecv_mode_t
01285 fsdp_get_sendrecv_mode(const fsdp_description_t *dsc)
01286 {
01287 if ( NULL == dsc )
01288 return FSDP_SENDRECV_UNDEFINED;
01289 return dsc->a_sendrecv_mode;
01290 }
01291
01292 fsdp_session_type_t
01293 fsdp_get_session_type(const fsdp_description_t *dsc)
01294 {
01295 if ( NULL == dsc )
01296 return FSDP_SESSION_TYPE_UNDEFINED;
01297 return dsc->a_type;
01298 }
01299
01300 unsigned int
01301 fsdp_get_media_count(const fsdp_description_t *dsc)
01302 {
01303 if ( NULL == dsc )
01304 return 0;
01305 return dsc->media_announcements_count;
01306 }
01307
01308 const fsdp_media_description_t*
01309 fsdp_get_media(const fsdp_description_t *dsc, unsigned int index)
01310 {
01311 if ( (index >= dsc->media_announcements_count) )
01312 return NULL;
01313 return dsc->media_announcements[index];
01314 }
01315
01316 fsdp_media_t
01317 fsdp_get_media_type(const fsdp_media_description_t *dsc)
01318 {
01319 if ( (NULL == dsc) )
01320 return FSDP_MEDIA_UNDEFINED;
01321 return dsc->media_type;
01322 }
01323
01324 unsigned int
01325 fsdp_get_media_port(const fsdp_media_description_t *dsc)
01326 {
01327 if ( (NULL == dsc) )
01328 return 0;
01329 return dsc->port;
01330 }
01331
01332 unsigned int
01333 fsdp_get_media_port_count(const fsdp_media_description_t *dsc)
01334 {
01335 if ( (NULL == dsc) )
01336 return 0;
01337 return dsc->port_count;
01338 }
01339
01340 fsdp_transport_protocol_t
01341 fsdp_get_media_transport_protocol(const fsdp_media_description_t *dsc)
01342 {
01343 if ( (NULL == dsc) )
01344 return FSDP_TP_UNDEFINED;
01345 return dsc->transport;
01346 }
01347
01348 unsigned int
01349 fsdp_get_media_formats_count(const fsdp_media_description_t *dsc)
01350 {
01351 if ( (NULL == dsc) )
01352 return 0;
01353 return dsc->formats_count;
01354 }
01355
01356 const char *
01357 fsdp_get_media_format(const fsdp_media_description_t *dsc, unsigned int index)
01358 {
01359 if ( (NULL == dsc) && (index < dsc->formats_count) )
01360 return NULL;
01361 return dsc->formats[index];
01362 }
01363
01364 const char *
01365 fsdp_get_media_title(const fsdp_media_description_t *dsc)
01366 {
01367 if ( (NULL == dsc) )
01368 return NULL;
01369 return dsc->i_title;
01370 }
01371
01372 fsdp_network_type_t
01373 fsdp_get_media_network_type(const fsdp_media_description_t *dsc)
01374 {
01375 if ( (NULL == dsc) )
01376 return FSDP_NETWORK_TYPE_UNDEFINED;
01377 return dsc->c_network_type;
01378 }
01379
01380 fsdp_address_type_t
01381 fsdp_get_media_address_type(const fsdp_media_description_t *dsc)
01382 {
01383 if ( (NULL == dsc) )
01384 return FSDP_ADDRESS_TYPE_UNDEFINED;
01385 return dsc->c_address_type;
01386 }
01387
01388 const char *
01389 fsdp_get_media_address(const fsdp_media_description_t *dsc)
01390 {
01391 if ( (NULL == dsc) )
01392 return NULL;
01393 return dsc->c_address.address;
01394 }
01395
01396 unsigned int
01397 fsdp_get_media_address_ttl(const fsdp_media_description_t *mdsc)
01398 {
01399 if ( NULL == mdsc )
01400 return 0;
01401 return mdsc->c_address.address_ttl;
01402 }
01403
01404 unsigned int
01405 fsdp_get_media_address_count(const fsdp_media_description_t *mdsc)
01406 {
01407 if ( NULL == mdsc)
01408 return 0;
01409 return mdsc->c_address.address_count;
01410 }
01411
01412 fsdp_bw_modifier_type_t
01413 fsdp_get_media_bw_modifier_type(const fsdp_media_description_t *dsc,
01414 unsigned int index)
01415 {
01416 if ( (NULL == dsc) || (index >= dsc->bw_modifiers_count) )
01417 return FSDP_BW_MOD_TYPE_UNDEFINED;
01418 return dsc->bw_modifiers[index].b_mod_type;
01419 }
01420
01421 const char *
01422 fsdp_get_media_bw_modifier_type_unknown(const fsdp_media_description_t *dsc,
01423 unsigned int index)
01424 {
01425 if ( (NULL == dsc) || (index >= dsc->bw_modifiers_count) ||
01426 (FSDP_BW_MOD_TYPE_UNKNOWN != dsc->bw_modifiers[index].b_mod_type) )
01427 return NULL;
01428 return dsc->bw_modifiers[index].b_unknown_bw_modt;
01429 }
01430
01431 unsigned long int
01432 fsdp_get_media_bw_value(const fsdp_media_description_t *dsc,
01433 unsigned int index)
01434 {
01435 if ( (NULL == dsc) || (index >= dsc->bw_modifiers_count) )
01436 return 0;
01437 return dsc->bw_modifiers[index].b_value;
01438 }
01439
01440 fsdp_encryption_method_t
01441 fsdp_get_media_encryption_method(const fsdp_media_description_t *dsc)
01442 {
01443 if ( (NULL == dsc) )
01444 return FSDP_ENCRYPTION_METHOD_UNDEFINED;
01445 return dsc->k_encryption_method;
01446 }
01447
01448 const char *
01449 fsdp_get_media_encryption_content(const fsdp_media_description_t *dsc)
01450 {
01451 if ( (NULL == dsc) )
01452 return NULL;
01453 return dsc->k_encryption_content;
01454 }
01455
01456 unsigned int
01457 fsdp_get_media_ptime(const fsdp_media_description_t *dsc)
01458 {
01459 if ( (NULL == dsc) )
01460 return 0;
01461 return dsc->a_ptime;
01462 }
01463
01464 unsigned int
01465 fsdp_get_media_maxptime(const fsdp_media_description_t *dsc)
01466 {
01467 if ( (NULL == dsc) )
01468 return 0;
01469 return dsc->a_maxptime;
01470 }
01471
01472 unsigned int
01473 fsdp_get_media_rtpmap_count(const fsdp_media_description_t *mdsc)
01474 {
01475 if ( NULL == mdsc)
01476 return 0;
01477 return mdsc->a_rtpmaps_count;
01478 }
01479
01480 const char *
01481 fsdp_get_media_rtpmap_payload_type(const fsdp_media_description_t *mdsc,
01482 unsigned int index)
01483 {
01484 if ( (NULL == mdsc) || (index >= mdsc->a_rtpmaps_count) )
01485 return NULL;
01486 return mdsc->a_rtpmaps[index]->pt;
01487 }
01488
01489 const char *
01490 fsdp_get_media_rtpmap_encoding_name(const fsdp_media_description_t *mdsc,
01491 unsigned int index)
01492 {
01493 if ( (NULL == mdsc) || (index >= mdsc->a_rtpmaps_count) )
01494 return NULL;
01495 return mdsc->a_rtpmaps[index]->encoding_name;
01496 }
01497
01498 unsigned int
01499 fsdp_get_media_rtpmap_clock_rate(const fsdp_media_description_t *mdsc,
01500 unsigned int index)
01501 {
01502 if ( (NULL == mdsc) || (index >= mdsc->a_rtpmaps_count) )
01503 return 0;
01504 return mdsc->a_rtpmaps[index]->clock_rate;
01505 }
01506
01507 const char *
01508 fsdp_get_media_rtpmap_encoding_parameters(const fsdp_description_t *mdsc,
01509 unsigned int index)
01510 {
01511 if ( (NULL == mdsc) || (index >= mdsc->a_rtpmaps_count) )
01512 return NULL;
01513 return mdsc->a_rtpmaps[index]->parameters;
01514 }
01515
01516 unsigned int
01517 fsdp_get_media_sdplang_count(const fsdp_media_description_t *mdsc)
01518 {
01519 if ( NULL == mdsc )
01520 return 0;
01521 return mdsc->a_sdplangs_count;
01522 }
01523
01524 const char *
01525 fsdp_get_media_sdplang(const fsdp_media_description_t *mdsc,
01526 unsigned int index)
01527 {
01528 if ( (NULL == mdsc) || (index >= mdsc->a_sdplangs_count) )
01529 return NULL;
01530 return mdsc->a_sdplangs[index];
01531 }
01532
01533 unsigned int
01534 fsdp_get_media_lang_count(const fsdp_media_description_t *mdsc)
01535 {
01536 if ( NULL == mdsc )
01537 return 0;
01538 return mdsc->a_langs_count;
01539 }
01540
01541 const char *
01542 fsdp_get_media_lang(const fsdp_media_description_t *mdsc,
01543 unsigned int index)
01544 {
01545 if ( (NULL == mdsc) || (index >= mdsc->a_langs_count) )
01546 return NULL;
01547 return mdsc->a_langs[index];
01548 }
01549
01550 unsigned int
01551 fsdp_get_media_fmtp_count(const fsdp_media_description_t *mdsc)
01552 {
01553 if ( NULL == mdsc )
01554 return 0;
01555 return mdsc->a_fmtps_count;
01556 }
01557
01558 const char *
01559 fsdp_get_media_fmtp(const fsdp_media_description_t *mdsc, unsigned int index)
01560 {
01561 if ( (NULL == mdsc) || (index >= mdsc->a_fmtps_count) )
01562 return NULL;
01563 return mdsc->a_fmtps[index];
01564 }
01565
01566 fsdp_orient_t
01567 fsdp_get_media_orient(const fsdp_media_description_t *dsc)
01568 {
01569 if ( (NULL == dsc) )
01570 return FSDP_ORIENT_UNDEFINED;
01571 return dsc->a_orient;
01572 }
01573
01574 fsdp_sendrecv_mode_t
01575 fsdp_get_media_sendrecv(const fsdp_media_description_t *dsc)
01576 {
01577 if ( (NULL == dsc) )
01578 return FSDP_SENDRECV_UNDEFINED;
01579 return dsc->a_sendrecv_mode;
01580 }
01581
01582 float
01583 fsdp_get_media_framerate(const fsdp_media_description_t *dsc)
01584 {
01585 if ( (NULL == dsc) )
01586 return 0;
01587 return dsc->a_framerate;
01588 }
01589
01590 unsigned int
01591 fsdp_get_media_quality(const fsdp_media_description_t *dsc)
01592 {
01593 if ( (NULL == dsc) )
01594 return 0;
01595 return dsc->a_quality;
01596 }
01597
01598 unsigned int
01599 fsdp_get_media_rtcp_port(const fsdp_media_description_t *dsc)
01600 {
01601 if ( (NULL == dsc) )
01602 return 0;
01603 return dsc->a_rtcp_port;
01604 }
01605
01606 fsdp_network_type_t
01607 fsdp_get_media_rtcp_network_type(const fsdp_media_description_t *dsc)
01608 {
01609 if ( (NULL == dsc) )
01610 return FSDP_NETWORK_TYPE_UNDEFINED;
01611 return dsc->a_rtcp_network_type;
01612 }
01613
01614 fsdp_address_type_t
01615 fsdp_get_media_rtcp_address_type(const fsdp_media_description_t *dsc)
01616 {
01617 if ( (NULL == dsc) )
01618 return FSDP_ADDRESS_TYPE_UNDEFINED;
01619 return dsc->a_rtcp_address_type;
01620 }
01621
01622 const char*
01623 fsdp_get_media_rtcp_address(const fsdp_media_description_t *dsc)
01624 {
01625 if ( (NULL == dsc) )
01626 return NULL;
01627 return dsc->a_rtcp_address;
01628 }
01629
01630 unsigned int
01631 fsdp_get_media_unidentified_attribute_count(const fsdp_media_description_t
01632 *mdsc)
01633 {
01634 if ( NULL == mdsc )
01635 return 0;
01636 return mdsc->unidentified_attributes_count;
01637 }
01638
01639 const char *
01640 fsdp_get_media_unidentified_attribute(const fsdp_media_description_t *mdsc,
01641 unsigned int index)
01642 {
01643 if ( NULL == mdsc || (index < mdsc->unidentified_attributes_count) )
01644 return NULL;
01645 return mdsc->unidentified_attributes[index];
01646 }