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=%[^:\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=%"MSFLENS"[^\r\n]",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],"RTP/SAVP",8) )
00499 media->transport = FSDP_TP_RTP_SAVP;
00500 else if ( !strncmp(fsdp_buf[2],"RTP/AVPF",8) )
00501 media->transport = FSDP_TP_RTP_AVPF;
00502 else if ( !strncmp(fsdp_buf[2],"RTP/SAVPF",9) )
00503 media->transport = FSDP_TP_RTP_SAVPF;
00504 else if ( !strncmp(fsdp_buf[2],"udp",3) )
00505 media->transport = FSDP_TP_UDP;
00506 else if ( !strncmp(fsdp_buf[2],"TCP",3) )
00507 media->transport = FSDP_TP_TCP;
00508 else if ( !strncmp(fsdp_buf[2],"UDPTL",5) )
00509 media->transport = FSDP_TP_UDPTL;
00510 else if ( !strncmp(fsdp_buf[2],"vat",3) )
00511 media->transport = FSDP_TP_VAT;
00512 else if ( !strncmp(fsdp_buf[2],"rtp",3) )
00513 media->transport = FSDP_TP_OLD_RTP;
00514 else
00515 return FSDPE_UNKNOWN_MEDIA_TRANSPORT;
00516 {
00517 unsigned int k = 0;
00518 char *s = longfsdp_buf;
00519 while ( NULL != ( s = strchr(s,' ')) ) {
00520 k++;
00521 if ( NULL != s )
00522 s++;
00523 }
00524 k++;
00525 media->formats_count = k;
00526 media->formats = calloc(k,sizeof(char*));
00527 s = longfsdp_buf;
00528 for ( k = 0; k < media->formats_count; k++ ) {
00529 char *space = strchr(s,' ');
00530 if ( NULL != space )
00531 *space = '\0';
00532 media->formats[k] = strdup(s);
00533 s = space + 1;
00534 }
00535 }
00536 NEXT_LINE(p);
00537 }
00538
00539
00540
00541 if ( !strncmp(p,"i=",2) && sscanf(p,"i=%"MLFLENS"[^\r\n]",longfsdp_buf) ) {
00542 media->i_title = strdup(longfsdp_buf);
00543 NEXT_LINE(p);
00544 } else {
00545
00546 }
00547
00548
00549
00550
00551 result = fsdp_parse_c(&p,&(media->c_network_type),
00552 &(media->c_address_type),&(media->c_address));
00553 if ( result != FSDPE_OK )
00554 return result;
00555
00556
00557
00558 result = fsdp_parse_b(&p,&(media->bw_modifiers),
00559 &(media->bw_modifiers_count));
00560 if ( FSDPE_OK != result )
00561 return result;
00562
00563
00564
00565
00566 result = fsdp_parse_k(&p,&(media->k_encryption_method),
00567 &(media->k_encryption_content));
00568 if ( result != FSDPE_OK )
00569 return result;
00570
00571
00572
00573
00574
00575
00576 while ( !strncmp(p,"a=",2) ) {
00577 if ( sscanf(p,"a=%[^:\r\n]:%"MLFLENS"[^\r\n]",fsdp_buf[0],longfsdp_buf)
00578 == 2 ) {
00579
00580 if ( !strncmp(fsdp_buf[0],"ptime",5) )
00581 media->a_ptime = strtoul(longfsdp_buf,NULL,10);
00582 else if ( !strncmp(fsdp_buf[0],"maxptime",8) )
00583 media->a_maxptime = strtoul(longfsdp_buf,NULL,10);
00584 else if ( !strncmp(fsdp_buf[0],"rtpmap",6) )
00585 fsdp_parse_rtpmap(&(media->a_rtpmaps),
00586 &(media->a_rtpmaps_count),longfsdp_buf);
00587 else if ( !strncmp(fsdp_buf[0],"orient",6) ) {
00588 if ( !strncmp(longfsdp_buf,"portrait",8) )
00589 media->a_orient = FSDP_ORIENT_PORTRAIT;
00590 else if ( !strncmp(longfsdp_buf,"landscape",9) )
00591 media->a_orient = FSDP_ORIENT_LANDSCAPE;
00592 else if ( !strncmp(longfsdp_buf,"seascape",9) )
00593 media->a_orient = FSDP_ORIENT_SEASCAPE;
00594 } else if ( !strncmp(fsdp_buf[0],"sdplang",7) ) {
00595 if ( NULL == dsc->a_sdplangs ) {
00596 media->a_sdplangs_count = 0;
00597 media->a_sdplangs =
00598 calloc(SDPLANGS_MAX_COUNT,sizeof(char*));
00599 }
00600 if ( media->a_sdplangs_count < SDPLANGS_MAX_COUNT ) {
00601 media->a_sdplangs[dsc->a_sdplangs_count] = strdup(longfsdp_buf);
00602 media->a_sdplangs_count++;
00603 }
00604 } else if ( !strncmp(fsdp_buf[0],"lang",4) ) {
00605 if ( NULL == dsc->a_langs ) {
00606 media->a_langs_count = 0;
00607 media->a_langs = calloc(SDPLANGS_MAX_COUNT,sizeof(char*));
00608 }
00609 if ( media->a_langs_count < SDPLANGS_MAX_COUNT ) {
00610 media->a_langs[dsc->a_langs_count] = strdup(longfsdp_buf);
00611 media->a_langs_count++;
00612 }
00613 } else if ( !strncmp(fsdp_buf[0],"framerate",9) )
00614 media->a_framerate = strtof(longfsdp_buf,NULL);
00615 else if ( !strncmp(fsdp_buf[0],"fmtp",4) ) {
00616 if ( NULL == media->a_fmtps ) {
00617 media->a_fmtps_count = 0;
00618 media->a_fmtps = calloc(SDPLANGS_MAX_COUNT,sizeof(char*));
00619 }
00620 if ( media->a_fmtps_count < SDPLANGS_MAX_COUNT ) {
00621 media->a_fmtps[media->a_fmtps_count] = strdup(longfsdp_buf);
00622 media->a_fmtps_count++;
00623 }
00624 } else if ( !strncmp(fsdp_buf[0],"rtcp",4) ) {
00625 int opts = 0;
00626
00627 opts = sscanf(longfsdp_buf,"%lu %2s %3s %"MSFLENS"s",
00628 &wuint[0],fsdp_buf[0],fsdp_buf[1],fsdp_buf[2]);
00629 if ( opts >= 1 ) {
00630 media->a_rtcp_port = wuint[0];
00631 if ( opts >= 2 ) {
00632 if ( !strncmp(fsdp_buf[0],"IN",2) ) {
00633 media->a_rtcp_network_type = FSDP_NETWORK_TYPE_INET;
00634 }
00635
00636 if ( opts >= 3 ) {
00637 if ( !strncmp(fsdp_buf[1],"IP4",3) )
00638 media->a_rtcp_address_type = FSDP_ADDRESS_TYPE_IPV4;
00639 else if ( !strncmp(fsdp_buf[1],"IP6",3) )
00640 media->a_rtcp_address_type = FSDP_ADDRESS_TYPE_IPV6;
00641 else
00642 return FSDPE_INVALID_CONNECTION_NETTYPE;
00643
00644 if ( opts >= 4)
00645 media->a_rtcp_address = strdup(fsdp_buf[2]);
00646 }
00647 }
00648 }
00649 } else {
00650
00651 *fsdp_buf[1] = '\0';
00652 strncat(fsdp_buf[1],fsdp_buf[0],MAXLONGFIELDLEN);
00653 strncat(fsdp_buf[1],":",MAXLONGFIELDLEN);
00654 strncat(fsdp_buf[1],longfsdp_buf,MAXLONGFIELDLEN);
00655 if ( NULL == media->unidentified_attributes ) {
00656 media->unidentified_attributes_count = 0;
00657 media->unidentified_attributes =
00658 calloc(UNIDENTIFIED_ATTRIBUTES_MAX_COUNT,sizeof(char*));
00659 }
00660 if ( media->unidentified_attributes_count <
00661 UNIDENTIFIED_ATTRIBUTES_MAX_COUNT ) {
00662 media->unidentified_attributes
00663 [media->unidentified_attributes_count] = strdup(fsdp_buf[1]);
00664 media->unidentified_attributes_count++;
00665 }
00666 }
00667 NEXT_LINE(p);
00668 } else if ( sscanf(p,"a=%"MSFLENS"[^\r\n]",fsdp_buf[0]) == 1 ) {
00669
00670 if ( !strncmp(fsdp_buf[0],"recvonly",8) )
00671 media->a_sendrecv_mode = FSDP_SENDRECV_RECVONLY;
00672 else if ( !strncmp(fsdp_buf[0],"sendonly",8) )
00673 media->a_sendrecv_mode = FSDP_SENDRECV_SENDONLY;
00674 else if ( !strncmp(fsdp_buf[0],"inactive",8) )
00675 media->a_sendrecv_mode = FSDP_SENDRECV_INACTIVE;
00676 else if ( !strncmp(fsdp_buf[0],"sendrecv",8) )
00677 media->a_sendrecv_mode = FSDP_SENDRECV_SENDRECV;
00678 else {
00679
00680 *longfsdp_buf = '\0';
00681 strncat(longfsdp_buf,fsdp_buf[0],MAXLONGFIELDLEN);
00682 if ( NULL == media->unidentified_attributes ) {
00683 media->unidentified_attributes_count = 0;
00684 media->unidentified_attributes =
00685 calloc(UNIDENTIFIED_ATTRIBUTES_MAX_COUNT,sizeof(char*));
00686 }
00687 if ( media->unidentified_attributes_count <
00688 UNIDENTIFIED_ATTRIBUTES_MAX_COUNT ) {
00689 media->unidentified_attributes
00690 [media->unidentified_attributes_count] = strdup(longfsdp_buf);
00691 media->unidentified_attributes_count++;
00692 }
00693 }
00694 NEXT_LINE(p);
00695 } else
00696 return FSDPE_INVALID_ATTRIBUTE;
00697 }
00698 }
00699 }
00700
00701
00702
00703 if ( NULL == dsc->c_address.address ) {
00704 unsigned int c;
00705 for ( c = 0; c < dsc->media_announcements_count; c++)
00706 if ( NULL == dsc->media_announcements[c]->c_address.address )
00707 return FSDPE_MISSING_CONNECTION_INFO;
00708 }
00709
00710
00711 if ( *p == '\0' )
00712 return FSDPE_OK;
00713 else
00714 return FSDPE_OVERFILLED;
00715 }
00716
00717 static fsdp_error_t
00718 fsdp_parse_c(const char **p, fsdp_network_type_t *ntype,
00719 fsdp_address_type_t *atype, fsdp_connection_address_t *address)
00720 {
00721 const unsigned int TEMPCHARS = 3;
00722 char fsdp_buf[TEMPCHARS][MAXSHORTFIELDLEN];
00723
00724 if ( !strncmp(*p,"c=",2) ) {
00725 if ( sscanf(*p,"c=%2s %3s %"MSFLENS"s",fsdp_buf[0],fsdp_buf[1],fsdp_buf[2]) ) {
00726 if ( !strncmp(fsdp_buf[0],"IN",2) ) {
00727 *ntype = FSDP_NETWORK_TYPE_INET;
00728 if ( !strncmp(fsdp_buf[1],"IP4",3) )
00729 *atype = FSDP_ADDRESS_TYPE_IPV4;
00730 else if ( !strncmp(fsdp_buf[1],"IP6",3) )
00731 *atype = FSDP_ADDRESS_TYPE_IPV6;
00732 else
00733 return FSDPE_INVALID_CONNECTION_NETTYPE;
00734 } else {
00735 return FSDPE_INVALID_CONNECTION_ADDRTYPE;
00736 }
00737 {
00738 char *slash = strchr(fsdp_buf[2],'/');
00739 if ( NULL == slash ) {
00740 address->address = strdup(fsdp_buf[2]);
00741 address->address_ttl = 0;
00742 address->address_count = 0;
00743 } else {
00744
00745 char *slash2;
00746 *slash = '\0';
00747 slash++;
00748 address->address = strdup(fsdp_buf[2]);
00749 slash2 = strchr(slash + 1,'/');
00750 if ( NULL == slash2 ) {
00751 address->address_ttl = strtol(slash,NULL,10);
00752 address->address_count = 0;
00753 } else {
00754 *slash2 = '\0';
00755 slash2++;
00756 address->address_ttl = strtol(slash,NULL,10);
00757 address->address_count = strtol(slash2,NULL,10);
00758 }
00759 }
00760 }
00761 NEXT_LINE(*p);
00762 } else {
00763 return FSDPE_INVALID_CONNECTION;
00764 }
00765 }
00766 return FSDPE_OK;
00767 }
00768
00769 static fsdp_error_t
00770 fsdp_parse_b(const char **p, fsdp_bw_modifier_t **bw_modifiers,
00771 unsigned int *bw_modifiers_count)
00772 {
00773 char fsdp_buf[MAXSHORTFIELDLEN];
00774 unsigned long int wuint;
00775 unsigned int i = 0;
00776 char *lp = (char*)*p;
00777
00778
00779 while ( !strncmp(lp,"b=",2) ) {
00780 NEXT_LINE(lp);
00781 i++;
00782 }
00783 *bw_modifiers = calloc(i,sizeof(fsdp_bw_modifier_t));
00784 *bw_modifiers_count = i;
00785
00786 while ( i > 0 ) {
00787 unsigned int index = *bw_modifiers_count - i;
00788 if ( 2 == sscanf(*p,"b=%"MSFLENS"[^:\r\n]:%lu",fsdp_buf,&wuint) ) {
00789 if ( !strncmp(fsdp_buf,"CT",2) )
00790 (*bw_modifiers)[index].b_mod_type = FSDP_BW_MOD_TYPE_CONFERENCE_TOTAL;
00791 else if ( !strncmp(fsdp_buf,"AS",2) )
00792 (*bw_modifiers)[index].b_mod_type = FSDP_BW_MOD_TYPE_APPLICATION_SPECIFIC;
00793 else if ( !strncmp(fsdp_buf,"RS",2) )
00794 (*bw_modifiers)[index].b_mod_type = FSDP_BW_MOD_TYPE_RTCP_SENDERS;
00795 else if ( !strncmp(fsdp_buf,"RR",2) )
00796 (*bw_modifiers)[index].b_mod_type = FSDP_BW_MOD_TYPE_RTCP_RECEIVERS;
00797 else {
00798 (*bw_modifiers)[index].b_mod_type = FSDP_BW_MOD_TYPE_UNKNOWN;
00799 (*bw_modifiers)[index].b_unknown_bw_modt = (char *)strdup(fsdp_buf);
00800 }
00801 (*bw_modifiers)[index].b_value = wuint;
00802 NEXT_LINE(*p);
00803 } else {
00804 *bw_modifiers_count -= i;
00805 return FSDPE_INVALID_BANDWIDTH;
00806 }
00807 i--;
00808 }
00809 return FSDPE_OK;
00810 }
00811
00812 static fsdp_error_t
00813 fsdp_parse_k(const char **p, fsdp_encryption_method_t *method, char **content)
00814 {
00815 char fsdp_buf[MAXSHORTFIELDLEN];
00816 char longfsdp_buf[MAXLONGFIELDLEN];
00817
00818 if ( !strncmp(*p,"k=",2) ) {
00819 if ( sscanf(*p,"k=prompt") ) {
00820 *method = FSDP_ENCRYPTION_METHOD_PROMPT;
00821 *content = NULL;
00822 NEXT_LINE(*p);
00823 } else {
00824 if ( sscanf(*p,"k=%6[^:\r\n]:%"MLFLENS"s",fsdp_buf,longfsdp_buf) ) {
00825 if ( !strncmp(fsdp_buf,"clear",5) )
00826 *method = FSDP_ENCRYPTION_METHOD_CLEAR;
00827 else if ( !strncmp(fsdp_buf,"base64",6) )
00828 *method = FSDP_ENCRYPTION_METHOD_BASE64;
00829 else if ( !strncmp(fsdp_buf,"uri",3) )
00830 *method = FSDP_ENCRYPTION_METHOD_URI;
00831 else
00832 return FSDPE_INVALID_ENCRYPTION_METHOD;
00833 *content = strdup(longfsdp_buf);
00834 NEXT_LINE(*p);
00835 }
00836 }
00837 }
00838 return FSDPE_OK;
00839 }
00840
00841 static fsdp_error_t
00842 fsdp_parse_rtpmap(fsdp_rtpmap_t ***rtpmap, unsigned int *counter,
00843 const char *value)
00844 {
00845 fsdp_error_t result = FSDPE_OK;
00846
00847 if ( 0 == *counter ) {
00848 *counter = 0;
00849 *rtpmap = calloc(MEDIA_RTPMAPS_MAX_COUNT,sizeof(fsdp_rtpmap_t*));
00850 }
00851 if ( *counter < MEDIA_RTPMAPS_MAX_COUNT ) {
00852 unsigned int c = *counter;
00853 fsdp_rtpmap_t **map = *rtpmap;
00854 char fsdp_buf[MAXSHORTFIELDLEN];
00855 char longfsdp_buf[MAXLONGFIELDLEN];
00856 map[c] = calloc(1,sizeof(fsdp_rtpmap_t));
00857
00858
00859
00860 if ( 2 == sscanf(value,"%s %s",fsdp_buf,longfsdp_buf) ) {
00861 char *slash1;
00862 map[c]->pt = strdup(fsdp_buf);
00863
00864 slash1 = strchr(longfsdp_buf,'/');
00865 if ( NULL == slash1 ) {
00866 result = FSDPE_INVALID_ATTRIBUTE_RTPMAP;
00867 } else {
00868 char *slash2;
00869 *slash1 = '\0';
00870 slash1++;
00871 map[c]->encoding_name = strdup(longfsdp_buf);
00872 slash2 = strchr(slash1,'/');
00873 if ( NULL != slash2 ) {
00874 *slash2 = '\0';
00875 slash2++;
00876 map[c]->parameters = strdup(slash2);
00877 }
00878 map[c]->clock_rate = strtol(slash1,NULL,10);
00879 }
00880 (*counter)++;
00881 }
00882 }
00883 return result;
00884 }
00885
00886 static fsdp_error_t
00887 fsdp_repeat_time_to_uint(const char *time, unsigned long int *seconds)
00888 {
00889 const unsigned long SECONDS_PER_DAY = 86400;
00890 const unsigned long SECONDS_PER_HOUR = 3600;
00891 const unsigned long SECONDS_PER_MINUTE = 60;
00892 char c;
00893 unsigned long int wuint;
00894
00895 if ( sscanf(time,"%lu%c",&wuint,&c) == 2 ) {
00896
00897 switch(c) {
00898 case 'd':
00899 *seconds = wuint * SECONDS_PER_DAY;
00900 break;
00901 case 'h':
00902 *seconds = wuint * SECONDS_PER_HOUR;
00903 break;
00904 case 'm':
00905 *seconds = wuint * SECONDS_PER_MINUTE;
00906 break;
00907 case 's':
00908 *seconds = wuint;
00909 break;
00910 default:
00911 return FSDPE_INVALID_REPEAT;
00912 break;
00913 }
00914 } else if ( sscanf(time,"%lu",&wuint) == 1 ) {
00915
00916 *seconds = wuint;
00917 } else {
00918 return FSDPE_INVALID_REPEAT;
00919 }
00920 return FSDPE_OK;
00921 }
00922
00923 const char *
00924 fsdp_get_wrong_string(const fsdp_description_t *dsc)
00925 {
00926 if ( NULL == dsc )
00927 return NULL;
00928 return NULL;
00929 }
00930
00931 unsigned int
00932 fsdp_get_version(const fsdp_description_t *dsc)
00933 {
00934 if ( NULL == dsc)
00935 return 0;
00936 return dsc->version;
00937 }
00938
00939 const char *
00940 fsdp_get_owner_username(const fsdp_description_t *dsc)
00941 {
00942 if ( NULL == dsc)
00943 return NULL;
00944 return dsc->o_username;
00945 }
00946
00947 const char *
00948 fsdp_get_session_id(const fsdp_description_t *dsc)
00949 {
00950 if ( NULL == dsc)
00951 return NULL;
00952 return dsc->o_session_id;
00953 }
00954
00955 const char *
00956 fsdp_get_announcement_version(const fsdp_description_t *dsc)
00957 {
00958 if ( NULL == dsc)
00959 return NULL;
00960 return dsc->o_announcement_version;
00961 }
00962
00963 fsdp_network_type_t
00964 fsdp_get_owner_network_type(const fsdp_description_t *dsc)
00965 {
00966 if ( NULL == dsc)
00967 return FSDP_NETWORK_TYPE_UNDEFINED;
00968 return dsc->o_network_type;
00969 }
00970
00971 fsdp_address_type_t
00972 fsdp_get_owner_address_type(const fsdp_description_t *dsc)
00973 {
00974 if ( NULL == dsc)
00975 return FSDP_ADDRESS_TYPE_UNDEFINED;
00976 return dsc->o_address_type;
00977 }
00978
00979 const char *
00980 fsdp_get_owner_address(const fsdp_description_t *dsc)
00981 {
00982 if ( NULL == dsc)
00983 return NULL;
00984 return dsc->o_address;
00985 }
00986
00987 const char *
00988 fsdp_get_name(const fsdp_description_t *dsc)
00989 {
00990 if ( NULL == dsc)
00991 return NULL;
00992 return dsc->s_name;
00993 }
00994
00995 const char *
00996 fsdp_get_information(const fsdp_description_t *dsc)
00997 {
00998 if ( NULL == dsc)
00999 return NULL;
01000 return dsc->i_information;
01001 }
01002
01003 const char *
01004 fsdp_get_uri(const fsdp_description_t *dsc)
01005 {
01006 if ( NULL == dsc)
01007 return NULL;
01008 return dsc->u_uri;
01009 }
01010
01011 unsigned int
01012 fsdp_get_emails_count(const fsdp_description_t *dsc)
01013 {
01014 if ( NULL == dsc)
01015 return 0;
01016 return dsc->emails_count;
01017 }
01018
01019 const char *
01020 fsdp_get_email(const fsdp_description_t *dsc, unsigned int index)
01021 {
01022 if ( (NULL == dsc) || (index >= dsc->emails_count) )
01023 return NULL;
01024 return dsc->emails[index];
01025 }
01026
01027 unsigned int
01028 fsdp_get_phones_count(const fsdp_description_t *dsc)
01029 {
01030 if ( NULL == dsc)
01031 return 0;
01032 return dsc->phones_count;
01033 }
01034
01035 const char *
01036 fsdp_get_phone(const fsdp_description_t *dsc, unsigned int index)
01037 {
01038 if ( (NULL == dsc ) || (index >= dsc->phones_count) )
01039 return NULL;
01040 return dsc->phones[index];
01041 }
01042
01043 fsdp_network_type_t
01044 fsdp_get_global_conn_network_type(const fsdp_description_t *dsc)
01045 {
01046 if ( NULL == dsc)
01047 return FSDP_NETWORK_TYPE_UNDEFINED;
01048 return dsc->c_network_type;
01049 }
01050
01051 fsdp_address_type_t
01052 fsdp_get_global_conn_address_type(const fsdp_description_t *dsc)
01053 {
01054 if ( NULL == dsc)
01055 return FSDP_ADDRESS_TYPE_UNDEFINED;
01056 return dsc->c_address_type;
01057 }
01058
01059 const char *
01060 fsdp_get_global_conn_address(const fsdp_description_t *dsc)
01061 {
01062 if ( NULL == dsc)
01063 return NULL;
01064 return dsc->c_address.address;
01065 }
01066
01067 unsigned int
01068 fsdp_get_global_conn_address_ttl(const fsdp_description_t *dsc)
01069 {
01070 if ( NULL == dsc)
01071 return 0;
01072 return dsc->c_address.address_ttl;
01073 }
01074
01075 unsigned int
01076 fsdp_get_global_conn_addresses_count(const fsdp_description_t *dsc)
01077 {
01078 if ( NULL == dsc)
01079 return 0;
01080 return dsc->c_address.address_count;
01081 }
01082
01083 unsigned int
01084 fsdp_get_bw_modifiers_count(const fsdp_description_t *dsc)
01085 {
01086 if ( (NULL == dsc) )
01087 return 0;
01088 return dsc->bw_modifiers_count;
01089 }
01090
01091 fsdp_bw_modifier_type_t
01092 fsdp_get_bw_modifier_type(const fsdp_description_t *dsc, unsigned int index)
01093 {
01094 if ( (NULL == dsc) || (index >= dsc->bw_modifiers_count) )
01095 return FSDP_BW_MOD_TYPE_UNDEFINED;
01096 return dsc->bw_modifiers[index].b_mod_type;
01097 }
01098
01099 const char *
01100 fsdp_get_bw_modifier_type_unknown(const fsdp_description_t *dsc,
01101 unsigned int index)
01102 {
01103 if ( (NULL == dsc) || (index >= dsc->bw_modifiers_count) ||
01104 (dsc->bw_modifiers[index].b_mod_type != FSDP_BW_MOD_TYPE_UNKNOWN) )
01105 return NULL;
01106 return dsc->bw_modifiers[index].b_unknown_bw_modt;
01107 }
01108
01109 unsigned long int
01110 fsdp_get_bw_value(const fsdp_description_t *dsc, unsigned int index)
01111 {
01112 if ( (NULL == dsc) || (index >= dsc->bw_modifiers_count) )
01113 return 0;
01114 return dsc->bw_modifiers[index].b_value;
01115 }
01116
01117 unsigned long int
01118 fsdp_get_periods_count(const fsdp_description_t *dsc)
01119 {
01120 if ( NULL == dsc)
01121 return 0;
01122 return dsc->time_periods_count;
01123 }
01124
01125 time_t
01126 fsdp_get_period_start(const fsdp_description_t *dsc, unsigned int index)
01127 {
01128 if ( (NULL == dsc) || (index >= dsc->time_periods_count) )
01129 return 0;
01130 return dsc->time_periods[index]->start;
01131 }
01132
01133 time_t
01134 fsdp_get_period_stop(const fsdp_description_t *dsc, unsigned int index)
01135 {
01136 if ( (NULL == dsc) || (index >= dsc->time_periods_count) )
01137 return 0;
01138 return dsc->time_periods[index]->stop;
01139 }
01140
01141 unsigned int
01142 fsdp_get_period_repeats_count(const fsdp_description_t *dsc,
01143 unsigned int index)
01144 {
01145 if ( (NULL == dsc) || (index >= dsc->time_periods_count) )
01146 return 0;
01147 return dsc->time_periods[index]->repeats_count;
01148 }
01149
01150 unsigned long int
01151 fsdp_get_period_repeat_interval(const fsdp_description_t *dsc,
01152 unsigned int index, unsigned int rindex)
01153 {
01154 if ( (NULL == dsc) || (index >= dsc->time_periods_count) )
01155 return 0;
01156 return dsc->time_periods[index]->repeats[rindex]->interval;
01157 }
01158
01159 unsigned long int
01160 fsdp_get_period_repeat_duration(const fsdp_description_t *dsc,
01161 unsigned int index, unsigned int rindex)
01162 {
01163 if ( (NULL == dsc) || (index >= dsc->time_periods_count) )
01164 return 0;
01165 return dsc->time_periods[index]->repeats[rindex]->duration;
01166 }
01167
01168 unsigned long int
01169 fsdp_get_period_repeat_offsets_count(const fsdp_description_t *dsc,
01170 unsigned int index, unsigned int rindex)
01171 {
01172 if ( (NULL == dsc) || (index >= dsc->time_periods_count) ||
01173 (rindex >= dsc->time_periods[index]->repeats_count) )
01174 return 0;
01175 return dsc->time_periods[index]->repeats[rindex]->offsets_count;
01176 }
01177
01178 unsigned long int
01179 fsdp_get_period_repeat_offsets(const fsdp_description_t *dsc,
01180 unsigned int index, unsigned int rindex,
01181 unsigned int oindex)
01182 {
01183 if ( (NULL == dsc) || (index >= dsc->time_periods_count) ||
01184 (rindex >= dsc->time_periods[index]->repeats_count) ||
01185 (oindex >= dsc->time_periods[index]->repeats[rindex]->offsets_count) )
01186 return 0;
01187 return dsc->time_periods[index]->repeats[rindex]->offsets[oindex];
01188 }
01189
01190 const char *
01191 fsdp_get_timezone_adj(const fsdp_description_t *dsc)
01192 {
01193 if ( NULL == dsc )
01194 return NULL;
01195 return dsc->timezone_adj;
01196 }
01197
01198 unsigned int
01199 fsdp_get_unidentified_attributes_count(const fsdp_description_t *dsc)
01200 {
01201 if ( NULL == dsc )
01202 return 0;
01203 return dsc->unidentified_attributes_count;
01204 }
01205
01206 const char *
01207 fsdp_get_unidentified_attribute(const fsdp_description_t *dsc,
01208 unsigned int index)
01209 {
01210 if ( NULL == dsc || (index >= dsc->unidentified_attributes_count) )
01211 return NULL;
01212 return dsc->unidentified_attributes[index];
01213 }
01214
01215 fsdp_encryption_method_t
01216 fsdp_get_encryption_method(const fsdp_description_t *dsc)
01217 {
01218 if ( NULL == dsc )
01219 return FSDP_ENCRYPTION_METHOD_UNDEFINED;
01220 return dsc->k_encryption_method;
01221 }
01222
01223 const char *
01224 fsdp_get_encryption_content(const fsdp_description_t *dsc)
01225 {
01226 if ( (NULL == dsc) ||
01227 (dsc->k_encryption_method == FSDP_ENCRYPTION_METHOD_UNDEFINED) )
01228 return NULL;
01229 return dsc->k_encryption_content;
01230 }
01231
01232 unsigned int
01233 fsdp_get_rtpmap_count(const fsdp_description_t *dsc)
01234 {
01235 if ( NULL == dsc)
01236 return 0;
01237 return dsc->a_rtpmaps_count;
01238 }
01239
01240 const char *
01241 fsdp_get_rtpmap_payload_type(const fsdp_description_t *dsc, unsigned int index)
01242 {
01243 if ( (NULL == dsc) || (index >= dsc->a_rtpmaps_count) )
01244 return NULL;
01245 return dsc->a_rtpmaps[index]->pt;
01246 }
01247
01248 const char *
01249 fsdp_get_rtpmap_encoding_name(const fsdp_description_t *dsc,
01250 unsigned int index)
01251 {
01252 if ( (NULL == dsc) || (index >= dsc->a_rtpmaps_count) )
01253 return NULL;
01254 return dsc->a_rtpmaps[index]->encoding_name;
01255 }
01256
01257 unsigned int
01258 fsdp_get_rtpmap_clock_rate(const fsdp_description_t *dsc, unsigned int index)
01259 {
01260 if ( (NULL == dsc) || (index >= dsc->a_rtpmaps_count) )
01261 return 0;
01262 return dsc->a_rtpmaps[index]->clock_rate;
01263 }
01264
01265 const char *
01266 fsdp_get_rtpmap_encoding_parameters(const fsdp_description_t *dsc,
01267 unsigned int index)
01268 {
01269 if ( (NULL == dsc) || (index >= dsc->a_rtpmaps_count) )
01270 return NULL;
01271 return dsc->a_rtpmaps[index]->parameters;
01272 }
01273
01274 const char *
01275 fsdp_get_str_att(const fsdp_description_t *dsc, fsdp_session_str_att_t att)
01276 {
01277 char *result;
01278 if ( NULL == dsc )
01279 return NULL;
01280 if ( att <= FSDP_LAST_SESSION_STR_ATT )
01281 result = dsc->a_str_attributes[att];
01282 else
01283 result = NULL;
01284 return result;
01285 }
01286
01287 unsigned int
01288 fsdp_get_sdplang_count(const fsdp_description_t *dsc)
01289 {
01290 if ( NULL == dsc )
01291 return 0;
01292 return dsc->a_sdplangs_count;
01293 }
01294
01295 const char *
01296 fsdp_get_sdplang(const fsdp_description_t *dsc, unsigned int index)
01297 {
01298 if ( (NULL == dsc) || (index >= dsc->a_sdplangs_count) )
01299 return NULL;
01300 return dsc->a_sdplangs[index];
01301 }
01302
01303 unsigned int
01304 fsdp_get_lang_count(const fsdp_description_t *dsc)
01305 {
01306 if ( NULL == dsc )
01307 return 0;
01308 return dsc->a_langs_count;
01309 }
01310
01311 const char *
01312 fsdp_get_lang(const fsdp_description_t *dsc, unsigned int index)
01313 {
01314 if ( (NULL == dsc) || (index >= dsc->a_langs_count) )
01315 return NULL;
01316 return dsc->a_langs[index];
01317 }
01318
01319 fsdp_sendrecv_mode_t
01320 fsdp_get_sendrecv_mode(const fsdp_description_t *dsc)
01321 {
01322 if ( NULL == dsc )
01323 return FSDP_SENDRECV_UNDEFINED;
01324 return dsc->a_sendrecv_mode;
01325 }
01326
01327 fsdp_session_type_t
01328 fsdp_get_session_type(const fsdp_description_t *dsc)
01329 {
01330 if ( NULL == dsc )
01331 return FSDP_SESSION_TYPE_UNDEFINED;
01332 return dsc->a_type;
01333 }
01334
01335 unsigned int
01336 fsdp_get_media_count(const fsdp_description_t *dsc)
01337 {
01338 if ( NULL == dsc )
01339 return 0;
01340 return dsc->media_announcements_count;
01341 }
01342
01343 const fsdp_media_description_t*
01344 fsdp_get_media(const fsdp_description_t *dsc, unsigned int index)
01345 {
01346 if ( (index >= dsc->media_announcements_count) )
01347 return NULL;
01348 return dsc->media_announcements[index];
01349 }
01350
01351 fsdp_media_t
01352 fsdp_get_media_type(const fsdp_media_description_t *dsc)
01353 {
01354 if ( (NULL == dsc) )
01355 return FSDP_MEDIA_UNDEFINED;
01356 return dsc->media_type;
01357 }
01358
01359 unsigned int
01360 fsdp_get_media_port(const fsdp_media_description_t *dsc)
01361 {
01362 if ( (NULL == dsc) )
01363 return 0;
01364 return dsc->port;
01365 }
01366
01367 unsigned int
01368 fsdp_get_media_ports_count(const fsdp_media_description_t *dsc)
01369 {
01370 if ( (NULL == dsc) )
01371 return 0;
01372 return dsc->port_count;
01373 }
01374
01375 fsdp_transport_protocol_t
01376 fsdp_get_media_transport_protocol(const fsdp_media_description_t *dsc)
01377 {
01378 if ( (NULL == dsc) )
01379 return FSDP_TP_UNDEFINED;
01380 return dsc->transport;
01381 }
01382
01383 unsigned int
01384 fsdp_get_media_formats_count(const fsdp_media_description_t *dsc)
01385 {
01386 if ( (NULL == dsc) )
01387 return 0;
01388 return dsc->formats_count;
01389 }
01390
01391 const char *
01392 fsdp_get_media_format(const fsdp_media_description_t *dsc, unsigned int index)
01393 {
01394 if ( (NULL == dsc) && (index < dsc->formats_count) )
01395 return NULL;
01396 return dsc->formats[index];
01397 }
01398
01399 const char *
01400 fsdp_get_media_title(const fsdp_media_description_t *dsc)
01401 {
01402 if ( (NULL == dsc) )
01403 return NULL;
01404 return dsc->i_title;
01405 }
01406
01407 fsdp_network_type_t
01408 fsdp_get_media_network_type(const fsdp_media_description_t *dsc)
01409 {
01410 if ( (NULL == dsc) )
01411 return FSDP_NETWORK_TYPE_UNDEFINED;
01412 return dsc->c_network_type;
01413 }
01414
01415 fsdp_address_type_t
01416 fsdp_get_media_address_type(const fsdp_media_description_t *dsc)
01417 {
01418 if ( (NULL == dsc) )
01419 return FSDP_ADDRESS_TYPE_UNDEFINED;
01420 return dsc->c_address_type;
01421 }
01422
01423 const char *
01424 fsdp_get_media_address(const fsdp_media_description_t *dsc)
01425 {
01426 if ( (NULL == dsc) )
01427 return NULL;
01428 return dsc->c_address.address;
01429 }
01430
01431 unsigned int
01432 fsdp_get_media_address_ttl(const fsdp_media_description_t *mdsc)
01433 {
01434 if ( NULL == mdsc )
01435 return 0;
01436 return mdsc->c_address.address_ttl;
01437 }
01438
01439 unsigned int
01440 fsdp_get_media_addresses_count(const fsdp_media_description_t *mdsc)
01441 {
01442 if ( NULL == mdsc)
01443 return 0;
01444 return mdsc->c_address.address_count;
01445 }
01446
01447 fsdp_bw_modifier_type_t
01448 fsdp_get_media_bw_modifier_type(const fsdp_media_description_t *dsc,
01449 unsigned int index)
01450 {
01451 if ( (NULL == dsc) || (index >= dsc->bw_modifiers_count) )
01452 return FSDP_BW_MOD_TYPE_UNDEFINED;
01453 return dsc->bw_modifiers[index].b_mod_type;
01454 }
01455
01456 const char *
01457 fsdp_get_media_bw_modifier_type_unknown(const fsdp_media_description_t *dsc,
01458 unsigned int index)
01459 {
01460 if ( (NULL == dsc) || (index >= dsc->bw_modifiers_count) ||
01461 (FSDP_BW_MOD_TYPE_UNKNOWN != dsc->bw_modifiers[index].b_mod_type) )
01462 return NULL;
01463 return dsc->bw_modifiers[index].b_unknown_bw_modt;
01464 }
01465
01466 unsigned long int
01467 fsdp_get_media_bw_value(const fsdp_media_description_t *dsc,
01468 unsigned int index)
01469 {
01470 if ( (NULL == dsc) || (index >= dsc->bw_modifiers_count) )
01471 return 0;
01472 return dsc->bw_modifiers[index].b_value;
01473 }
01474
01475 fsdp_encryption_method_t
01476 fsdp_get_media_encryption_method(const fsdp_media_description_t *dsc)
01477 {
01478 if ( (NULL == dsc) )
01479 return FSDP_ENCRYPTION_METHOD_UNDEFINED;
01480 return dsc->k_encryption_method;
01481 }
01482
01483 const char *
01484 fsdp_get_media_encryption_content(const fsdp_media_description_t *dsc)
01485 {
01486 if ( (NULL == dsc) )
01487 return NULL;
01488 return dsc->k_encryption_content;
01489 }
01490
01491 unsigned int
01492 fsdp_get_media_ptime(const fsdp_media_description_t *dsc)
01493 {
01494 if ( (NULL == dsc) )
01495 return 0;
01496 return dsc->a_ptime;
01497 }
01498
01499 unsigned int
01500 fsdp_get_media_maxptime(const fsdp_media_description_t *dsc)
01501 {
01502 if ( (NULL == dsc) )
01503 return 0;
01504 return dsc->a_maxptime;
01505 }
01506
01507 unsigned int
01508 fsdp_get_media_rtpmap_count(const fsdp_media_description_t *mdsc)
01509 {
01510 if ( NULL == mdsc)
01511 return 0;
01512 return mdsc->a_rtpmaps_count;
01513 }
01514
01515 const char *
01516 fsdp_get_media_rtpmap_payload_type(const fsdp_media_description_t *mdsc,
01517 unsigned int index)
01518 {
01519 if ( (NULL == mdsc) || (index >= mdsc->a_rtpmaps_count) )
01520 return NULL;
01521 return mdsc->a_rtpmaps[index]->pt;
01522 }
01523
01524 const char *
01525 fsdp_get_media_rtpmap_encoding_name(const fsdp_media_description_t *mdsc,
01526 unsigned int index)
01527 {
01528 if ( (NULL == mdsc) || (index >= mdsc->a_rtpmaps_count) )
01529 return NULL;
01530 return mdsc->a_rtpmaps[index]->encoding_name;
01531 }
01532
01533 unsigned int
01534 fsdp_get_media_rtpmap_clock_rate(const fsdp_media_description_t *mdsc,
01535 unsigned int index)
01536 {
01537 if ( (NULL == mdsc) || (index >= mdsc->a_rtpmaps_count) )
01538 return 0;
01539 return mdsc->a_rtpmaps[index]->clock_rate;
01540 }
01541
01542 const char *
01543 fsdp_get_media_rtpmap_encoding_parameters(const fsdp_description_t *mdsc,
01544 unsigned int index)
01545 {
01546 if ( (NULL == mdsc) || (index >= mdsc->a_rtpmaps_count) )
01547 return NULL;
01548 return mdsc->a_rtpmaps[index]->parameters;
01549 }
01550
01551 unsigned int
01552 fsdp_get_media_sdplang_count(const fsdp_media_description_t *mdsc)
01553 {
01554 if ( NULL == mdsc )
01555 return 0;
01556 return mdsc->a_sdplangs_count;
01557 }
01558
01559 const char *
01560 fsdp_get_media_sdplang(const fsdp_media_description_t *mdsc,
01561 unsigned int index)
01562 {
01563 if ( (NULL == mdsc) || (index >= mdsc->a_sdplangs_count) )
01564 return NULL;
01565 return mdsc->a_sdplangs[index];
01566 }
01567
01568 unsigned int
01569 fsdp_get_media_lang_count(const fsdp_media_description_t *mdsc)
01570 {
01571 if ( NULL == mdsc )
01572 return 0;
01573 return mdsc->a_langs_count;
01574 }
01575
01576 const char *
01577 fsdp_get_media_lang(const fsdp_media_description_t *mdsc,
01578 unsigned int index)
01579 {
01580 if ( (NULL == mdsc) || (index >= mdsc->a_langs_count) )
01581 return NULL;
01582 return mdsc->a_langs[index];
01583 }
01584
01585 unsigned int
01586 fsdp_get_media_fmtp_count(const fsdp_media_description_t *mdsc)
01587 {
01588 if ( NULL == mdsc )
01589 return 0;
01590 return mdsc->a_fmtps_count;
01591 }
01592
01593 const char *
01594 fsdp_get_media_fmtp(const fsdp_media_description_t *mdsc, unsigned int index)
01595 {
01596 if ( (NULL == mdsc) || (index >= mdsc->a_fmtps_count) )
01597 return NULL;
01598 return mdsc->a_fmtps[index];
01599 }
01600
01601 fsdp_orient_t
01602 fsdp_get_media_orient(const fsdp_media_description_t *dsc)
01603 {
01604 if ( (NULL == dsc) )
01605 return FSDP_ORIENT_UNDEFINED;
01606 return dsc->a_orient;
01607 }
01608
01609 fsdp_sendrecv_mode_t
01610 fsdp_get_media_sendrecv(const fsdp_media_description_t *dsc)
01611 {
01612 if ( (NULL == dsc) )
01613 return FSDP_SENDRECV_UNDEFINED;
01614 return dsc->a_sendrecv_mode;
01615 }
01616
01617 float
01618 fsdp_get_media_framerate(const fsdp_media_description_t *dsc)
01619 {
01620 if ( (NULL == dsc) )
01621 return 0;
01622 return dsc->a_framerate;
01623 }
01624
01625 unsigned int
01626 fsdp_get_media_quality(const fsdp_media_description_t *dsc)
01627 {
01628 if ( (NULL == dsc) )
01629 return 0;
01630 return dsc->a_quality;
01631 }
01632
01633 unsigned int
01634 fsdp_get_media_rtcp_port(const fsdp_media_description_t *dsc)
01635 {
01636 if ( (NULL == dsc) )
01637 return 0;
01638 return dsc->a_rtcp_port;
01639 }
01640
01641 fsdp_network_type_t
01642 fsdp_get_media_rtcp_network_type(const fsdp_media_description_t *dsc)
01643 {
01644 if ( (NULL == dsc) )
01645 return FSDP_NETWORK_TYPE_UNDEFINED;
01646 return dsc->a_rtcp_network_type;
01647 }
01648
01649 fsdp_address_type_t
01650 fsdp_get_media_rtcp_address_type(const fsdp_media_description_t *dsc)
01651 {
01652 if ( (NULL == dsc) )
01653 return FSDP_ADDRESS_TYPE_UNDEFINED;
01654 return dsc->a_rtcp_address_type;
01655 }
01656
01657 const char*
01658 fsdp_get_media_rtcp_address(const fsdp_media_description_t *dsc)
01659 {
01660 if ( (NULL == dsc) )
01661 return NULL;
01662 return dsc->a_rtcp_address;
01663 }
01664
01665 unsigned int
01666 fsdp_get_media_unidentified_attributes_count(const fsdp_media_description_t
01667 *mdsc)
01668 {
01669 if ( NULL == mdsc )
01670 return 0;
01671 return mdsc->unidentified_attributes_count;
01672 }
01673
01674 const char *
01675 fsdp_get_media_unidentified_attribute(const fsdp_media_description_t *mdsc,
01676 unsigned int index)
01677 {
01678 if ( NULL == mdsc || (index < mdsc->unidentified_attributes_count) )
01679 return NULL;
01680 return mdsc->unidentified_attributes[index];
01681 }