formatter.c

Go to the documentation of this file.
00001 /*
00002   This file is part of FreeSDP
00003   Copyright (C) 2001,2002,2003,2004 Federico Montesino Pouzols <fedemp@altern.org>
00004   
00005   FreeSDP is free software; you can redistribute it and/or modify it
00006   under the terms of the GNU General Public License as published by
00007   the Free Software Foundation; either version 2 of the License, or
00008   (at your option) any later version.
00009 
00010   FreeSDP is distributed in the hope that it will be useful,
00011   but WITHOUT ANY WARRANTY; without even the implied warranty of
00012   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013   GNU General Public License for more details.
00014 
00015   You should have received a copy of the GNU General Public License
00016   along with this program; if not, write to the Free Software
00017   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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   /* TODO: add sanity checks */
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   /* TODO: *dsc->built = 1; */
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   /* iterative calls to */
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   /* while ( len < maxsize ) */
00142   /* `v=' line (protocol version) */
00143   len += snprintf(text_description,100,"v=0\r\n");
00144 
00145   /***************************************************************************/
00146   /* A) parse session-level description                                      */
00147   /***************************************************************************/
00148   /* o= line (owner/creator and session identifier). */
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   /* s= line (session name). */
00156   len += snprintf(text_description + len,100,"s=%s\r\n",dsc->s_name);
00157 
00158   /* `i=' line (session information) [optional] */
00159   if ( dsc->i_information != NULL )
00160     len += snprintf(text_description + len,100,"i=%s\r\n",dsc->i_information);
00161 
00162   /* `u=' line (URI of description) [optional] */
00163   if ( dsc->u_uri != NULL )
00164     len += snprintf(text_description + len,100,"u=%s\r\n",dsc->u_uri);
00165 
00166   /* `e=' lines (email address) [zero or more] */
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   /* `p=' lines (phone number) [zero or more] */
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   /* `c=' line (connection information - not required if included in all media) [optional] */
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   /* `b=' lines (bandwidth information) [optional] */
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   /* `t=' lines (time the session is active) [1 or more] */
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     /* `r' lines [zero or more repeat times for each t=] */
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]); /* FIX offsets */
00225     }
00226   }
00227   
00228   /* `z=' line (time zone adjustments) [zero or more] */
00229   if ( NULL != dsc->timezone_adj)
00230     len += snprintf(text_description + len,100,"z=%s\r\n",dsc->timezone_adj);
00231 
00232   /* `k=' line (encryption key) [optional] */
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   /* `a=' lines (zero or more session attribute lines) [optional] */
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     /* attributes not recognized by FreeSDP */
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   /* B) print media-level descriptions                                       */
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     {       /* `m=' line (media name, transport address and format list) */
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     /* `b=' lines (bandwidth information) [optional] */
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     /* `k=' line (encryption key) [optional] */
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     /* `a=' lines (zero or more media attribute lines) [optional] */
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     /* attributes not recognized by FreeSDP */
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   /* this should be a macro: */
00442   if ( (len + 5) > maxsize ) 
00443     return FSDPE_BUFFER_OVERFLOW;
00444   len += 5;
00445   
00446   /* strncpy */
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 ) /* FIX */
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 ) /* FIX */
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 ) { /* FIX */
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     /* FIX */
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     /* FIX */
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     /* TODO repeat->offsets = strdup(offsets); */
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; /* FIX */
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   /* TODO: check that format is valid */
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 ) { /* FIX */
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 }

Generated on Wed May 3 13:49:06 2006 for FreeSDP by  doxygen 1.4.6