00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00026 #include "formatterpriv.h"
00027
00028 const char *bandwidth_modifier_strings[] = {
00029 "", "", "CT", "AS", "RS", "RR"
00030 };
00031
00032 const char *network_type_strings[] = {
00033 "", "IN"
00034 };
00035
00036 const char *address_type_strings[] = {
00037 "", "IP4", "IP6"
00038 };
00039
00040 const char *bw_mod_type_strings[] = {
00041 "", "CT", "AS", "RS", "RR"
00042 };
00043
00044 const char *encryption_method_strings[] = {
00045 "", "clear", "base64", "uri"
00046 };
00047
00048 const char *sendrecv_mode_strings[] = {
00049 "", "sendrecv", "recvonly", "sendonly", "inactive"
00050 };
00051
00052 const char *session_type_strings[] = {
00053 "", "broadcast", "meeting", "moderated", "test", "H332"
00054 };
00055
00056 const char *media_strings[] ={
00057 "", "audio", "video", "text", "application", "data", "control"
00058 };
00059
00060 const char *tp_strings[] = {
00061 "", "RTP/AVP", "RTP/SAVP", "RTP/AVPF", "RTP/SAVPF", "udp", "TCP", "UDPTL",
00062 "vat", "rtp", "H.320"
00063 };
00064
00065 const char *orient_strings[] = {
00066 "", "portrait", "landscape", "seascape"
00067 };
00068
00069 fsdp_error_t
00070 fsdp_make_description(fsdp_description_t **dsc,
00071 unsigned int sdp_version,
00072 const char *session_name, const char *session_id,
00073 const char *announcement_version,
00074 const char *owner_username,
00075 fsdp_network_type_t owner_nt,
00076 fsdp_address_type_t owner_at,
00077 const char *owner_address,
00078 time_t start, time_t stop)
00079 {
00080 fsdp_description_t *obj;
00081
00082 if ( (NULL == dsc) || (NULL == session_name) || (NULL == session_id) ||
00083 (NULL == announcement_version) ||
00084 (NULL == owner_username) || (NULL == owner_address) )
00085 return FSDPE_INVALID_PARAMETER;
00086
00087 *dsc = fsdp_description_new();
00088 obj = *dsc;
00089
00090
00091 obj->version = sdp_version;
00092 obj->o_username = strdup(owner_username);
00093 obj->o_session_id = strdup(session_id);
00094 obj->o_announcement_version = strdup(announcement_version);
00095 obj->o_network_type = owner_nt;
00096 obj->o_address_type = owner_at;
00097 obj->o_address = strdup(owner_address);
00098 obj->s_name = strdup(session_name);
00099 obj->time_periods =
00100 calloc(TIME_PERIODS_MAX_COUNT,sizeof(fsdp_time_period_t*));
00101 obj->time_periods[0] = calloc(1,sizeof(fsdp_time_period_t));
00102 obj->time_periods[0]->start = start;
00103 obj->time_periods[0]->stop = stop;
00104 obj->time_periods_count = 1;
00105 obj->time_periods[0]->repeats =
00106 calloc(REPEATS_MAX_COUNT,sizeof(fsdp_repeat_t*));
00107 obj->time_periods[0]->repeats_count = 0;
00108
00109
00110 return FSDPE_OK;
00111 }
00112
00113 fsdp_error_t
00114 fsdp_format(const fsdp_description_t *dsc, char **text_description)
00115 {
00116 char *result;
00117 size_t len = 1024;
00118
00119 if ( (NULL == dsc) || (NULL == text_description) )
00120 return FSDPE_INVALID_PARAMETER;
00121
00122 result = malloc(len);
00123
00124
00125 fsdp_format_bounded(dsc,result,len);
00126
00127 *text_description = result;
00128
00129 return FSDPE_OK;
00130 }
00131
00132 fsdp_error_t
00133 fsdp_format_bounded(const fsdp_description_t *dsc, char *text_description,
00134 size_t maxsize)
00135 {
00136 unsigned int i = 0, len = 0;
00137
00138 if ( (NULL == dsc) || (NULL == text_description) )
00139 return FSDPE_INVALID_PARAMETER;
00140
00141
00142
00143 len += snprintf(text_description,100,"v=0\r\n");
00144
00145
00146
00147
00148
00149 len += snprintf(text_description + len,100,
00150 "o=%s %s %s %2s %3s %s\r\n",dsc->o_username,
00151 dsc->o_session_id,dsc->o_announcement_version,
00152 network_type_strings[dsc->c_network_type],
00153 address_type_strings[dsc->o_address_type],dsc->o_address);
00154
00155
00156 len += snprintf(text_description + len,100,"s=%s\r\n",dsc->s_name);
00157
00158
00159 if ( dsc->i_information != NULL )
00160 len += snprintf(text_description + len,100,"i=%s\r\n",dsc->i_information);
00161
00162
00163 if ( dsc->u_uri != NULL )
00164 len += snprintf(text_description + len,100,"u=%s\r\n",dsc->u_uri);
00165
00166
00167 for ( i = 0; i < dsc->emails_count; i++ ) {
00168 len += snprintf(text_description + len,100,"e=%s\r\n",dsc->emails[i]);
00169 }
00170
00171
00172 for ( i = 0; i < dsc->phones_count; i++ ) {
00173 len += snprintf(text_description + len,100,"p=%s\r\n",dsc->phones[i]);
00174 }
00175
00176
00177 if ( FSDP_NETWORK_TYPE_UNDEFINED != dsc->c_network_type ) {
00178 if ( 0 == dsc->c_address.address_ttl ) {
00179 len += snprintf(text_description + len,100,"c=%s %s %s\r\n",
00180 network_type_strings[dsc->c_network_type],
00181 address_type_strings[dsc->c_address_type],
00182 dsc->c_address.address);
00183 } else {
00184 if ( 0 == dsc->c_address.address_count ) {
00185 len += snprintf(text_description + len,100,"c=%s %s %s/%d\r\n",
00186 network_type_strings[dsc->c_network_type],
00187 address_type_strings[dsc->c_address_type],
00188 dsc->c_address.address,dsc->c_address.address_ttl);
00189 } else {
00190 len += snprintf(text_description + len,100,"c=%s %s %s/%d/%d\r\n",
00191 network_type_strings[dsc->c_network_type],
00192 address_type_strings[dsc->c_address_type],
00193 dsc->c_address.address,dsc->c_address.address_ttl,
00194 dsc->c_address.address_count);
00195 }
00196 }
00197 }
00198
00199
00200 for (i = 0; i < dsc->bw_modifiers_count; i++) {
00201 fsdp_bw_modifier_type_t mt = dsc->bw_modifiers[i].b_mod_type;
00202 if ( FSDP_BW_MOD_TYPE_UNKNOWN == mt ) {
00203 len += snprintf(text_description + len,100,"b=%s:%lu\r\n",
00204 dsc->bw_modifiers[i].b_unknown_bw_modt,
00205 dsc->bw_modifiers[i].b_value);
00206 } else {
00207 len += snprintf(text_description + len,100,"b=%s:%lu\r\n",
00208 bw_mod_type_strings[mt],dsc->bw_modifiers[i].b_value);
00209 }
00210 }
00211
00212
00213 for (i = 0; i < dsc->time_periods_count; i++) {
00214 unsigned int j;
00215 len += snprintf(text_description + len,100,"t=%lu %lu\r\n",
00216 dsc->time_periods[i]->start + NTP_EPOCH_OFFSET,
00217 dsc->time_periods[i]->stop + NTP_EPOCH_OFFSET);
00218
00219
00220 for ( j = 0; j < dsc->time_periods[i]->repeats_count; j++ ) {
00221 fsdp_repeat_t *repeat = dsc->time_periods[i]->repeats[j];
00222 len += snprintf(text_description + len,100,"r=%lu %lu %lu\r\n",
00223 repeat->interval, repeat->duration,
00224 repeat->offsets[0]);
00225 }
00226 }
00227
00228
00229 if ( NULL != dsc->timezone_adj)
00230 len += snprintf(text_description + len,100,"z=%s\r\n",dsc->timezone_adj);
00231
00232
00233 if ( FSDP_ENCRYPTION_METHOD_UNDEFINED == dsc->k_encryption_method ) {
00234 ;
00235 } else if ( FSDP_ENCRYPTION_METHOD_PROMPT == dsc->k_encryption_method ) {
00236 len += snprintf(text_description + len,100,"k=prompt\r\n");
00237 } else {
00238 len += snprintf(text_description + len,100,"k=%s:%s\r\n",
00239 encryption_method_strings[dsc->k_encryption_method],
00240 dsc->k_encryption_content);
00241 }
00242
00243
00244 {
00245 unsigned int j;
00246
00247 if ( NULL != dsc->a_str_attributes[FSDP_SESSION_STR_ATT_CATEGORY] )
00248 len += snprintf(text_description + len,100,"a=cat:%s\r\n",
00249 dsc->a_str_attributes[FSDP_SESSION_STR_ATT_CATEGORY]);
00250
00251 if ( NULL != dsc->a_str_attributes[FSDP_SESSION_STR_ATT_CATEGORY] )
00252 len += snprintf(text_description + len,100,"a=keywds:%s\r\n",
00253 dsc->a_str_attributes[FSDP_SESSION_STR_ATT_CATEGORY]);
00254
00255 if ( NULL != dsc->a_str_attributes[FSDP_SESSION_STR_ATT_TOOL] )
00256 len += snprintf(text_description + len,100,"a=tool:%s\r\n",
00257 dsc->a_str_attributes[FSDP_SESSION_STR_ATT_TOOL]);
00258
00259 for ( j = 0; j < dsc->a_rtpmaps_count; j++ ) {
00260 fsdp_rtpmap_t *rtpmap = dsc->a_rtpmaps[j];
00261 if ( NULL == rtpmap->parameters )
00262 len += snprintf(text_description + len,100,
00263 "a=rtpmap:%s %s/%u\r\n",
00264 rtpmap->pt,rtpmap->encoding_name,rtpmap->clock_rate);
00265 else
00266 len += snprintf(text_description + len,100,
00267 "a=rtpmap:%s %s/%u/%s\r\n",
00268 rtpmap->pt,rtpmap->encoding_name,rtpmap->clock_rate,
00269 rtpmap->parameters);
00270 }
00271
00272 if ( FSDP_SENDRECV_UNDEFINED != dsc->a_sendrecv_mode )
00273 len += snprintf(text_description + len,100,"a=%s\r\n",
00274 sendrecv_mode_strings[dsc->a_sendrecv_mode]);
00275
00276 if ( FSDP_SESSION_TYPE_UNDEFINED != dsc->a_type )
00277 len += snprintf(text_description + len,100,"a=type:%s\r\n",
00278 session_type_strings[dsc->a_type]);
00279
00280 if ( NULL != dsc->a_str_attributes[FSDP_SESSION_STR_ATT_CHARSET] )
00281 len += snprintf(text_description + len,100,"a=charset:%s\r\n",
00282 dsc->a_str_attributes[FSDP_SESSION_STR_ATT_CHARSET]);
00283
00284 for ( j = 0; j < dsc->a_sdplangs_count; j++ ) {
00285 len += snprintf(text_description + len,100,"a=sdplang:%s\r\n",
00286 dsc->a_sdplangs[j]);
00287 }
00288
00289 for ( j = 0; j < dsc->a_langs_count; j++ ) {
00290 len += snprintf(text_description + len,100,"a=lang:%s\r\n",
00291 dsc->a_langs[j]);
00292 }
00293
00294
00295 for ( j = 0; j < dsc->unidentified_attributes_count; j++ ) {
00296 len += snprintf(text_description + len,100,"a=%s\r\n",
00297 dsc->unidentified_attributes[j]);
00298 }
00299 }
00300
00301
00302
00303
00304 for ( i = 0; i < dsc->media_announcements_count; i++) {
00305 unsigned int j;
00306 fsdp_media_announcement_t *ann = dsc->media_announcements[i];
00307 {
00308 if ( 0 == ann->port_count )
00309 len += snprintf(text_description + len,100,"m=%s %d %s",
00310 media_strings[ann->media_type],ann->port,
00311 tp_strings[ann->transport]);
00312 else
00313 len += snprintf(text_description + len,100,"m=%s %d/%d %s",
00314 media_strings[ann->media_type],
00315 ann->port,ann->port_count,
00316 tp_strings[ann->transport]);
00317
00318 for ( j = 0; j < ann->formats_count; j++ )
00319 len += snprintf(text_description + len,100," %s",ann->formats[j]);
00320 len += snprintf(text_description + len,100,"\r\n");
00321 }
00322
00323 if ( ann->i_title != NULL )
00324 len += snprintf(text_description + len,100,"i=%s\r\n",
00325 ann->i_title);
00326
00327 if ( FSDP_NETWORK_TYPE_UNDEFINED != ann->c_network_type ) {
00328 if ( 0 == ann->c_address.address_ttl ) {
00329 len += snprintf(text_description + len,100,"c=%s %s %s\r\n",
00330 network_type_strings[ann->c_network_type],
00331 address_type_strings[ann->c_address_type],
00332 ann->c_address.address);
00333 } else {
00334 if ( 0 == ann->c_address.address_count ) {
00335 len += snprintf(text_description + len,100,"c=%s %s %s/%d\r\n",
00336 network_type_strings[ann->c_network_type],
00337 address_type_strings[dsc->c_address_type],
00338 ann->c_address.address,ann->c_address.address_ttl);
00339 } else {
00340 len += snprintf(text_description + len,100,"c=%s %s %s/%d/%d\r\n",
00341 network_type_strings[ann->c_network_type],
00342 address_type_strings[ann->c_address_type],
00343 ann->c_address.address,ann->c_address.address_ttl,
00344 ann->c_address.address_count);
00345 }
00346 }
00347 }
00348
00349
00350 for (j = 0; j < ann->bw_modifiers_count; j++) {
00351 fsdp_bw_modifier_type_t mt = ann->bw_modifiers[j].b_mod_type;
00352 if ( FSDP_BW_MOD_TYPE_UNKNOWN == mt )
00353 len += snprintf(text_description + len,100,"b=%s:%lu\r\n",
00354 ann->bw_modifiers[j].b_unknown_bw_modt,
00355 ann->bw_modifiers[j].b_value);
00356 else
00357 len += snprintf(text_description + len,100,"b=%s:%lu\r\n",
00358 bandwidth_modifier_strings[ann->bw_modifiers[j].b_mod_type],
00359 ann->bw_modifiers[j].b_value);
00360 }
00361
00362
00363 if ( FSDP_ENCRYPTION_METHOD_UNDEFINED == ann->k_encryption_method ) {
00364 ;
00365 } else if ( FSDP_ENCRYPTION_METHOD_PROMPT == ann->k_encryption_method ) {
00366 len += snprintf(text_description + len,100,"k=prompt\r\n");
00367 } else {
00368 len += snprintf(text_description + len,100,"k=%s:%s\r\n",
00369 encryption_method_strings[ann->k_encryption_method],
00370 ann->k_encryption_content);
00371 }
00372
00373
00374 if ( 0 != ann->a_ptime )
00375 len += snprintf(text_description + len,100,"a=ptime:%lu\r\n",
00376 ann->a_ptime);
00377
00378 if ( 0 != ann->a_maxptime )
00379 len += snprintf(text_description + len,100,"a=maxptime:%lu\r\n",
00380 ann->a_maxptime);
00381
00382 for ( j = 0; j < ann->a_rtpmaps_count; j++ ) {
00383 fsdp_rtpmap_t *rtpmap = ann->a_rtpmaps[j];
00384 if ( NULL == rtpmap->parameters )
00385 len += snprintf(text_description + len,100,
00386 "a=rtpmap:%s %s/%u\r\n",
00387 rtpmap->pt,rtpmap->encoding_name,rtpmap->clock_rate);
00388 else
00389 len += snprintf(text_description + len,100,
00390 "a=rtpmap:%s %s/%u/%s\r\n",
00391 rtpmap->pt,rtpmap->encoding_name,rtpmap->clock_rate,
00392 rtpmap->parameters);
00393 }
00394
00395 if ( FSDP_ORIENT_UNDEFINED != ann->a_orient )
00396 len += snprintf(text_description + len,100,"a=orient:%s\r\n",
00397 orient_strings[ann->a_orient]);
00398
00399 if ( FSDP_SENDRECV_UNDEFINED != ann->a_sendrecv_mode )
00400 len += snprintf(text_description + len,100,"a=%s\r\n",
00401 sendrecv_mode_strings[ann->a_sendrecv_mode]);
00402
00403 for ( j = 0; j < ann->a_sdplangs_count; j++ ) {
00404 len += snprintf(text_description + len,100,"a=sdplang:%s\r\n",
00405 ann->a_sdplangs[j]);
00406 }
00407
00408 for ( j = 0; j < ann->a_langs_count; j++ ) {
00409 len += snprintf(text_description + len,100,"a=lang:%s\r\n",
00410 ann->a_langs[j]);
00411 }
00412
00413 if ( 0.0 != ann->a_framerate )
00414 len += snprintf(text_description + len,100,"a=framerate:%f\r\n",
00415 ann->a_framerate);
00416
00417 if ( 0 != ann->a_quality )
00418 len += snprintf(text_description + len,100,"a=quality:%ul\r\n",
00419 ann->a_quality);
00420
00421 for ( j = 0; j < ann->a_fmtps_count; j++ ) {
00422 len += snprintf(text_description + len,100,"a=lang:%s\r\n",
00423 ann->a_fmtps[j]);
00424 }
00425
00426 if ( NULL != ann->a_rtcp_address ) {
00427 len += snprintf(text_description + len,100,"a=rtcp:%u %s %s %s\r\n",
00428 ann->a_rtcp_port,
00429 network_type_strings[ann->a_rtcp_network_type],
00430 address_type_strings[ann->a_rtcp_address_type],
00431 ann->a_rtcp_address);
00432 }
00433
00434
00435 for ( j = 0; j < ann->unidentified_attributes_count; j++ ) {
00436 len += snprintf(text_description + len,100,"a=%s\r\n",
00437 ann->unidentified_attributes[j]);
00438 }
00439 }
00440
00441
00442 if ( (len + 5) > maxsize )
00443 return FSDPE_BUFFER_OVERFLOW;
00444 len += 5;
00445
00446
00447 return FSDPE_INTERNAL_ERROR;
00448 }
00449
00450
00451 fsdp_error_t
00452 fsdp_set_information(fsdp_description_t *dsc, const char *info)
00453 {
00454 if ( (NULL == dsc) || (NULL == info) )
00455 return FSDPE_INVALID_PARAMETER;
00456
00457 if ( NULL != dsc->i_information )
00458 free(dsc->i_information);
00459 dsc->i_information = strdup(info);
00460 return FSDPE_OK;
00461 }
00462
00463 fsdp_error_t
00464 fsdp_set_uri(fsdp_description_t *dsc, const char *uri)
00465 {
00466 if ( (NULL == dsc) || (NULL == uri) )
00467 return FSDPE_INVALID_PARAMETER;
00468
00469 if ( NULL != dsc->u_uri )
00470 free(dsc->u_uri);
00471 dsc->u_uri = strdup(uri);
00472 return FSDPE_OK;
00473 }
00474
00475 fsdp_error_t
00476 fsdp_add_email(fsdp_description_t *dsc, char *email)
00477 {
00478 if ( (NULL == dsc) || (NULL == email) ) {
00479 return FSDPE_INVALID_PARAMETER;
00480 }
00481 if ( NULL == dsc->emails ) {
00482 dsc->emails_count = 0;
00483 dsc->emails = calloc(EMAILS_MAX_COUNT,sizeof(char*));
00484 }
00485 if ( dsc->emails_count < EMAILS_MAX_COUNT )
00486 dsc->emails[dsc->emails_count++] = strdup(email);
00487
00488 return FSDPE_OK;
00489 }
00490
00491 fsdp_error_t
00492 fsdp_add_phone(fsdp_description_t *dsc, char *phone)
00493 {
00494 if ( (NULL == dsc) || (NULL == phone) ) {
00495 return FSDPE_INVALID_PARAMETER;
00496 }
00497 if ( NULL == dsc->phones ) {
00498 dsc->phones_count = 0;
00499 dsc->phones = calloc(PHONES_MAX_COUNT,sizeof(char*));
00500 }
00501 if ( dsc->phones_count < PHONES_MAX_COUNT )
00502 dsc->phones[dsc->phones_count++] = strdup(phone);
00503
00504 return FSDPE_OK;
00505 }
00506
00507 fsdp_error_t
00508 fsdp_set_conn_address(fsdp_description_t *dsc, fsdp_network_type_t nt,
00509 fsdp_address_type_t at, const char *address,
00510 unsigned int address_ttl, unsigned int address_count)
00511 {
00512 if ( (NULL == dsc) || (NULL == address) ) {
00513 return FSDPE_INVALID_PARAMETER;
00514 }
00515 dsc->c_network_type = nt;
00516 dsc->c_address_type = at;
00517 if ( NULL != dsc->c_address.address )
00518 free(dsc->c_address.address);
00519 dsc->c_address.address = strdup(address);
00520 dsc->c_address.address_ttl = address_ttl;
00521 dsc->c_address.address_count = address_count;
00522 return FSDPE_OK;
00523 }
00524
00525 fsdp_error_t
00526 fsdp_add_bw_info(fsdp_description_t *dsc,
00527 fsdp_bw_modifier_type_t mt, unsigned long int value,
00528 const char *unk_bmt)
00529 {
00530 if ( (NULL == dsc) ||
00531 ((FSDP_BW_MOD_TYPE_UNKNOWN == mt) && (NULL == unk_bmt)) ) {
00532 return FSDPE_INVALID_PARAMETER;
00533 }
00534 if ( NULL == dsc->bw_modifiers ) {
00535 dsc->bw_modifiers_count = 0;
00536 dsc->bw_modifiers =
00537 calloc(BW_MODIFIERS_MAX_COUNT,sizeof(fsdp_bw_modifier_t));
00538 }
00539 if ( dsc->bw_modifiers_count < BW_MODIFIERS_MAX_COUNT ) {
00540 fsdp_bw_modifier_t *bwm = &(dsc->bw_modifiers[dsc->bw_modifiers_count]);
00541 bwm->b_mod_type = mt;
00542 bwm->b_value = value;
00543 if ( FSDP_BW_MOD_TYPE_UNKNOWN == mt) {
00544 bwm->b_unknown_bw_modt = strdup(unk_bmt);
00545 }
00546 dsc->bw_modifiers_count++;
00547 }
00548
00549 return FSDPE_OK;
00550 }
00551
00552 fsdp_error_t
00553 fsdp_add_period(fsdp_description_t *dsc, time_t start, time_t stop)
00554 {
00555 if ( (NULL == dsc) )
00556 return FSDPE_INVALID_PARAMETER;
00557
00558 if ( dsc->time_periods_count < TIME_PERIODS_MAX_COUNT ) {
00559
00560 fsdp_time_period_t *period;
00561 dsc->time_periods[dsc->time_periods_count] =
00562 calloc(1,sizeof(fsdp_time_period_t));
00563 period = dsc->time_periods[dsc->time_periods_count];
00564 period->start = start;
00565 period->stop = stop;
00566 dsc->time_periods_count++;
00567 }
00568 return FSDPE_OK;
00569 }
00570
00571 fsdp_error_t
00572 fsdp_add_repeat(fsdp_description_t *dsc, unsigned long int interval,
00573 unsigned long int duration, const char *offsets)
00574 {
00575 fsdp_time_period_t *period;
00576
00577 if ( (NULL == dsc) || (NULL == offsets) )
00578 return FSDPE_INVALID_PARAMETER;
00579
00580 period = dsc->time_periods[dsc->time_periods_count];
00581 if ( NULL == period->repeats ) {
00582 period->repeats_count = 0;
00583 period->repeats =
00584 calloc(REPEATS_MAX_COUNT,sizeof(fsdp_repeat_t*));
00585 }
00586 if ( period->repeats_count < REPEATS_MAX_COUNT ) {
00587
00588 fsdp_repeat_t *repeat;
00589 period->repeats[period->repeats_count] = calloc(1,sizeof(fsdp_repeat_t));
00590 repeat = period->repeats[period->repeats_count];
00591 repeat->interval = interval;
00592 repeat->duration = duration;
00593
00594 repeat->offsets = NULL;
00595 period->repeats_count++;
00596 }
00597 return FSDPE_OK;
00598 }
00599
00600 fsdp_error_t
00601 fsdp_set_encryption(fsdp_description_t *dsc, fsdp_encryption_method_t emethod,
00602 const char *ekey)
00603 {
00604 if ( (NULL == dsc) ||
00605 ((FSDP_ENCRYPTION_METHOD_PROMPT != emethod)
00606 && (NULL == ekey)) ) {
00607 return FSDPE_INVALID_PARAMETER;
00608 }
00609 dsc->k_encryption_method = emethod;
00610 if ( NULL != dsc->k_encryption_content )
00611 free(dsc->k_encryption_content);
00612 if ( FSDP_ENCRYPTION_METHOD_PROMPT != emethod )
00613 dsc->k_encryption_content = strdup(ekey);
00614 return FSDPE_OK;
00615 }
00616
00617 fsdp_error_t
00618 fsdp_set_timezone_adj(fsdp_description_t *dsc, const char *adj)
00619 {
00620 if ( (NULL == dsc) || (NULL == adj) )
00621 return FSDPE_INVALID_PARAMETER;
00622 if ( NULL != dsc->timezone_adj )
00623 free(dsc->timezone_adj);
00624 dsc->timezone_adj = strdup(adj);
00625 return FSDPE_OK;
00626 }
00627
00628 fsdp_error_t
00629 fsdp_set_str_att(fsdp_description_t *dsc, fsdp_session_str_att_t att,
00630 const char *value)
00631 {
00632 if ( NULL == dsc )
00633 return FSDPE_INVALID_PARAMETER;
00634 if ( att <= FSDP_LAST_SESSION_STR_ATT ) {
00635 if ( NULL != dsc->a_str_attributes[att] )
00636 free(dsc->a_str_attributes[att]);
00637 dsc->a_str_attributes[att] = strdup(value);
00638 } else
00639 return FSDPE_INVALID_PARAMETER;
00640 return FSDPE_OK;
00641 }
00642
00643 fsdp_error_t
00644 fsdp_add_sdplang(fsdp_description_t *dsc, const char* lang)
00645 {
00646 if ( (NULL == dsc) || (NULL == lang) )
00647 return FSDPE_INVALID_PARAMETER;
00648
00649 if ( NULL == dsc->a_sdplangs ) {
00650 dsc->a_sdplangs_count = 0;
00651 dsc->a_sdplangs =
00652 calloc(SDPLANGS_MAX_COUNT,sizeof(char*));
00653 }
00654 if ( dsc->a_sdplangs_count < SDPLANGS_MAX_COUNT ) {
00655 dsc->a_sdplangs[dsc->a_sdplangs_count] = strdup(lang);
00656 dsc->a_sdplangs_count++;
00657 }
00658 return FSDPE_OK;
00659 }
00660
00661 fsdp_error_t
00662 fsdp_add_lang(fsdp_description_t *dsc, const char* lang)
00663 {
00664 if ( (NULL == dsc) || (NULL == lang) )
00665 return FSDPE_INVALID_PARAMETER;
00666
00667 if ( NULL == dsc->a_langs ) {
00668 dsc->a_langs_count = 0;
00669 dsc->a_langs = calloc(SDPLANGS_MAX_COUNT,sizeof(char*));
00670 }
00671 if ( dsc->a_langs_count < SDPLANGS_MAX_COUNT ) {
00672 dsc->a_langs[dsc->a_langs_count] = strdup(lang);
00673 dsc->a_langs_count++;
00674 }
00675 return FSDPE_OK;
00676 }
00677
00678 fsdp_error_t
00679 fsdp_add_rtpmap(fsdp_description_t *dsc, const char* payload_type,
00680 const char *encoding_name, unsigned int rate,
00681 const char *parameters)
00682 {
00683 if ( (NULL == dsc) || (NULL == encoding_name) )
00684 return FSDPE_INVALID_PARAMETER;
00685
00686 if ( NULL == dsc->a_rtpmaps ) {
00687 dsc->a_rtpmaps_count = 0;
00688 dsc->a_rtpmaps = calloc(MEDIA_RTPMAPS_MAX_COUNT,sizeof(fsdp_rtpmap_t*));
00689 }
00690 {
00691 unsigned int c = dsc->a_rtpmaps_count;
00692 if ( c < MEDIA_RTPMAPS_MAX_COUNT ) {
00693 dsc->a_rtpmaps[c] = calloc(1,sizeof(fsdp_rtpmap_t));
00694 dsc->a_rtpmaps[c]->pt = strdup(payload_type);
00695 dsc->a_rtpmaps[c]->encoding_name = strdup(encoding_name);
00696 dsc->a_rtpmaps[c]->clock_rate = rate;
00697 if ( NULL != parameters )
00698 dsc->a_rtpmaps[c]->parameters = strdup(parameters);
00699 dsc->a_rtpmaps_count++;
00700 }
00701 }
00702 return FSDPE_OK;
00703 }
00704
00705 fsdp_error_t
00706 fsdp_set_sendrecv(fsdp_description_t *dsc, fsdp_sendrecv_mode_t mode)
00707 {
00708 if ( (NULL == dsc) )
00709 return FSDPE_INVALID_PARAMETER;
00710 dsc->a_sendrecv_mode = mode;
00711 return FSDPE_OK;
00712 }
00713
00714 fsdp_error_t
00715 fsdp_set_session_type(fsdp_description_t *dsc, fsdp_session_type_t type)
00716 {
00717 if ( (NULL == dsc) )
00718 return FSDPE_INVALID_PARAMETER;
00719 dsc->a_type = type;
00720 return FSDPE_OK;
00721 }
00722
00723 fsdp_error_t
00724 fsdp_add_media(fsdp_description_t *dsc, fsdp_media_description_t *const mdsc)
00725 {
00726 if ( (NULL == dsc) || (NULL == mdsc) )
00727 return FSDPE_INVALID_PARAMETER;
00728 if ( NULL == dsc->media_announcements ) {
00729 dsc->media_announcements_count = 0;
00730 dsc->media_announcements =
00731 calloc(MEDIA_ANNOUNCEMENTS_MAX_COUNT,sizeof(fsdp_media_announcement_t*));
00732 }
00733 if ( dsc->media_announcements_count < MEDIA_ANNOUNCEMENTS_MAX_COUNT )
00734 dsc->media_announcements[dsc->media_announcements_count++] = mdsc;
00735 return FSDPE_OK;
00736 }
00737
00738 fsdp_error_t
00739 fsdp_make_media(fsdp_media_description_t **mdsc, fsdp_media_t type,
00740 unsigned int port, unsigned int port_count,
00741 fsdp_transport_protocol_t tp, const char *format)
00742 {
00743 fsdp_media_description_t *obj;
00744
00745 if ( (NULL == mdsc) || (NULL == format) )
00746 return FSDPE_INVALID_PARAMETER;
00747
00748 *mdsc = calloc(1,sizeof(fsdp_media_description_t));
00749 obj = *mdsc;
00750 obj->media_type = type;
00751 obj->port = port;
00752 obj->port_count = port_count;
00753 obj->transport = tp;
00754
00755 obj->formats = calloc(MEDIA_FORMATS_MAX_COUNT,sizeof(char*));
00756 obj->formats[0] = strdup(format);
00757 obj->formats_count = 1;
00758 obj->a_rtpmaps = NULL;
00759 return FSDPE_OK;
00760 }
00761
00762 fsdp_error_t
00763 fsdp_add_media_format(fsdp_media_description_t *mdsc, const char *format)
00764 {
00765 if ( (NULL == mdsc) || (NULL == format) ) {
00766 return FSDPE_INVALID_PARAMETER;
00767 }
00768 if ( mdsc->formats_count < MEDIA_FORMATS_MAX_COUNT ) {
00769 mdsc->formats[mdsc->formats_count] = strdup(format);
00770 mdsc->formats_count++;
00771 }
00772 return FSDPE_OK;
00773 }
00774
00775 fsdp_error_t
00776 fsdp_set_media_title(fsdp_media_description_t *mdsc, const char *title)
00777 {
00778 if ( (NULL == mdsc) || (NULL == title) ) {
00779 return FSDPE_INVALID_PARAMETER;
00780 }
00781 if ( NULL != mdsc->i_title )
00782 free(mdsc->i_title);
00783 mdsc->i_title = strdup(title);
00784 return FSDPE_OK;
00785 }
00786
00787 fsdp_error_t
00788 fsdp_set_media_conn_address(fsdp_media_description_t *mdsc,
00789 fsdp_network_type_t nt, fsdp_address_type_t at,
00790 const char *address, unsigned int address_ttl,
00791 unsigned int address_count)
00792 {
00793 if ( (NULL == mdsc) || (NULL == address) ) {
00794 return FSDPE_INVALID_PARAMETER;
00795 }
00796 mdsc->c_network_type = nt;
00797 mdsc->c_address_type = at;
00798 if ( NULL != mdsc->c_address.address )
00799 free(mdsc->c_address.address);
00800 mdsc->c_address.address = strdup(address);
00801 mdsc->c_address.address_ttl = address_ttl;
00802 mdsc->c_address.address_count = address_count;
00803 return FSDPE_OK;
00804 }
00805
00806 fsdp_error_t
00807 fsdp_add_media_bw_info(fsdp_media_description_t *mdsc,
00808 fsdp_bw_modifier_type_t mt,
00809 unsigned long int value, const char *unk_bmt)
00810 {
00811 if ( (NULL == mdsc) ||
00812 ((FSDP_BW_MOD_TYPE_UNKNOWN == mt) && (NULL == unk_bmt)) ) {
00813 return FSDPE_INVALID_PARAMETER;
00814 }
00815 if ( NULL == mdsc->bw_modifiers ) {
00816 mdsc->bw_modifiers_count = 0;
00817 mdsc->bw_modifiers = calloc(BW_MODIFIERS_MAX_COUNT,sizeof(char*));
00818 }
00819 if ( mdsc->bw_modifiers_count < BW_MODIFIERS_MAX_COUNT ) {
00820 fsdp_bw_modifier_t *bwm = &(mdsc->bw_modifiers[mdsc->bw_modifiers_count]);
00821 bwm->b_mod_type = mt;
00822 bwm->b_value = value;
00823 if ( FSDP_BW_MOD_TYPE_UNKNOWN== mt) {
00824 bwm->b_unknown_bw_modt = strdup(unk_bmt);
00825 }
00826 mdsc->bw_modifiers_count++;
00827 }
00828 return FSDPE_OK;
00829 }
00830
00831 fsdp_error_t
00832 fsdp_set_media_encryption(fsdp_media_description_t *mdsc,
00833 fsdp_encryption_method_t emethod, const char *ekey)
00834 {
00835 if ( (NULL == mdsc) ||
00836 ((FSDP_ENCRYPTION_METHOD_PROMPT != emethod)
00837 && (NULL == ekey)) ) {
00838 return FSDPE_INVALID_PARAMETER;
00839 }
00840 mdsc->k_encryption_method = emethod;
00841 if ( NULL != mdsc->k_encryption_content )
00842 free(mdsc->k_encryption_content);
00843 if ( FSDP_ENCRYPTION_METHOD_PROMPT != emethod )
00844 mdsc->k_encryption_content = strdup(ekey);
00845 return FSDPE_OK;
00846 }
00847
00848 fsdp_error_t
00849 fsdp_set_media_ptime(fsdp_media_description_t *mdsc, unsigned int ptime)
00850 {
00851 if ( (NULL == mdsc) )
00852 return FSDPE_INVALID_PARAMETER;
00853 mdsc->a_ptime = ptime;
00854 return FSDPE_OK;
00855 }
00856
00857 fsdp_error_t
00858 fsdp_set_media_maxptime(fsdp_media_description_t *mdsc, unsigned int maxptime)
00859 {
00860 if ( (NULL == mdsc) )
00861 return FSDPE_INVALID_PARAMETER;
00862 mdsc->a_maxptime = maxptime;
00863 return FSDPE_OK;
00864 }
00865
00866
00867 fsdp_error_t
00868 fsdp_add_media_fmtp(fsdp_media_description_t *mdsc, const char* fmtp)
00869 {
00870 if ( (NULL == mdsc) || (NULL == fmtp) )
00871 return FSDPE_INVALID_PARAMETER;
00872
00873 if ( NULL == mdsc->a_fmtps ) {
00874 mdsc->a_fmtps_count = 0;
00875 mdsc->a_fmtps = calloc(SDPLANGS_MAX_COUNT,sizeof(char*));
00876 }
00877 if ( mdsc->a_fmtps_count < SDPLANGS_MAX_COUNT ) {
00878 mdsc->a_fmtps[mdsc->a_fmtps_count] = strdup(fmtp);
00879 mdsc->a_fmtps_count++;
00880 }
00881 return FSDPE_OK;
00882 }
00883
00884 fsdp_error_t
00885 fsdp_set_media_orient(fsdp_media_description_t *mdsc, fsdp_orient_t orient)
00886 {
00887 if ( (NULL == mdsc) )
00888 return FSDPE_INVALID_PARAMETER;
00889 mdsc->a_orient = orient;
00890 return FSDPE_OK;
00891 }
00892
00893 fsdp_error_t
00894 fsdp_add_media_sdplang(fsdp_media_description_t *mdsc, const char* lang)
00895 {
00896 if ( (NULL == mdsc) || (NULL == lang) )
00897 return FSDPE_INVALID_PARAMETER;
00898
00899 if ( NULL == mdsc->a_sdplangs ) {
00900 mdsc->a_sdplangs_count = 0;
00901 mdsc->a_sdplangs =
00902 calloc(SDPLANGS_MAX_COUNT,sizeof(char*));
00903 }
00904 if ( mdsc->a_sdplangs_count < SDPLANGS_MAX_COUNT ) {
00905 mdsc->a_sdplangs[mdsc->a_sdplangs_count] = strdup(lang);
00906 mdsc->a_sdplangs_count++;
00907 }
00908 return FSDPE_OK;
00909 }
00910
00911 fsdp_error_t
00912 fsdp_add_media_lang(fsdp_media_description_t *mdsc, const char* lang)
00913 {
00914 if ( (NULL == mdsc) || (NULL == lang) )
00915 return FSDPE_INVALID_PARAMETER;
00916
00917 if ( NULL == mdsc->a_langs ) {
00918 mdsc->a_langs_count = 0;
00919 mdsc->a_langs = calloc(SDPLANGS_MAX_COUNT,sizeof(char*));
00920 }
00921 if ( mdsc->a_langs_count < SDPLANGS_MAX_COUNT ) {
00922 mdsc->a_langs[mdsc->a_langs_count] = strdup(lang);
00923 mdsc->a_langs_count++;
00924 }
00925 return FSDPE_OK;
00926 }
00927
00928 fsdp_error_t
00929 fsdp_set_media_sendrecv(fsdp_media_description_t *mdsc,
00930 fsdp_sendrecv_mode_t mode)
00931 {
00932 if ( (NULL == mdsc) )
00933 return FSDPE_INVALID_PARAMETER;
00934 mdsc->a_sendrecv_mode = mode;
00935 return FSDPE_OK;
00936 }
00937
00938 fsdp_error_t
00939 fsdp_set_media_framerate(fsdp_media_description_t *mdsc, float rate)
00940 {
00941 if ( (NULL == mdsc) )
00942 return FSDPE_INVALID_PARAMETER;
00943 mdsc->a_framerate = rate;
00944 return FSDPE_OK;
00945 }
00946
00947 fsdp_error_t
00948 fsdp_set_media_quality(fsdp_media_description_t *mdsc, unsigned int q)
00949 {
00950 if ( (NULL == mdsc) )
00951 return FSDPE_INVALID_PARAMETER;
00952 mdsc->a_quality = q;
00953 return FSDPE_OK;
00954 }
00955
00956 fsdp_error_t
00957 fsdp_add_media_rtpmap(fsdp_media_description_t *mdsc, const char* payload_type,
00958 const char *encoding_name, unsigned int rate,
00959 const char *parameters)
00960 {
00961 if ( (NULL == mdsc) || (NULL == encoding_name) )
00962 return FSDPE_INVALID_PARAMETER;
00963
00964 if ( NULL == mdsc->a_rtpmaps ) {
00965 mdsc->a_rtpmaps_count = 0;
00966 mdsc->a_rtpmaps = calloc(MEDIA_RTPMAPS_MAX_COUNT,sizeof(fsdp_rtpmap_t*));
00967 }
00968 {
00969 unsigned int c = mdsc->a_rtpmaps_count;
00970 if ( c < MEDIA_RTPMAPS_MAX_COUNT ) {
00971 mdsc->a_rtpmaps[c] = calloc(1,sizeof(fsdp_rtpmap_t));
00972 mdsc->a_rtpmaps[c]->pt = strdup(payload_type);
00973 mdsc->a_rtpmaps[c]->encoding_name = strdup(encoding_name);
00974 mdsc->a_rtpmaps[c]->clock_rate = rate;
00975 if ( NULL != parameters )
00976 mdsc->a_rtpmaps[c]->parameters = strdup(parameters);
00977 mdsc->a_rtpmaps_count++;
00978 }
00979 }
00980 return FSDPE_OK;
00981 }
00982
00983 fsdp_error_t
00984 fsdp_set_media_rtcp(fsdp_media_description_t *mdsc, unsigned int port,
00985 fsdp_network_type_t nt, fsdp_address_type_t at,
00986 const char *address)
00987 {
00988 if ( (NULL == mdsc) || (NULL == address) )
00989 return FSDPE_INVALID_PARAMETER;
00990 mdsc->a_rtcp_port = port;
00991 mdsc->a_rtcp_network_type = nt;
00992 mdsc->a_rtcp_address_type = at;
00993 if ( NULL != mdsc->a_rtcp_address )
00994 free(mdsc->a_rtcp_address);
00995 mdsc->a_rtcp_address = strdup(address);
00996 return FSDPE_OK;
00997 }