2 The oSIP library implements the Session Initiation Protocol (SIP -rfc3261-)
3 Copyright (C) 2001,2002,2003 Aymeric MOIZARD jack@atosc.org
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include <osipparser2/osip_port.h>
23 #include <osipparser2/osip_rfc3264.h>
24 #include <osip_rfc3264i.h> /* internal include */
27 * Initialize negotiation facility..
28 * @param config The element to work on.
30 int osip_rfc3264_init (struct osip_rfc3264 **config)
34 cnf = (osip_rfc3264_t *) osip_malloc (sizeof(osip_rfc3264_t));
37 memset(cnf, 0, sizeof(osip_rfc3264_t));
44 * Free negotiation facility.
45 * @param config The element to work on.
47 void osip_rfc3264_free (struct osip_rfc3264 *config)
49 osip_rfc3264_t *cnf = (osip_rfc3264_t*) config;
51 if (config==NULL) return;
53 for (i=0;i<MAX_AUDIO_CODECS; i++)
55 if (cnf->audio_medias[i]!=NULL)
57 sdp_media_free(cnf->audio_medias[i]);
58 cnf->audio_medias[i] = NULL;
61 for (i=0;i<MAX_VIDEO_CODECS; i++)
63 if (cnf->video_medias[i]!=NULL)
65 sdp_media_free(cnf->video_medias[i]);
66 cnf->video_medias[i] = NULL;
69 for (i=0;i<MAX_T38_CODECS; i++)
71 if (cnf->t38_medias[i]!=NULL)
73 sdp_media_free(cnf->t38_medias[i]);
74 cnf->t38_medias[i] = NULL;
77 for (i=0;i<MAX_APP_CODECS; i++)
79 if (cnf->app_medias[i]!=NULL)
81 sdp_media_free(cnf->app_medias[i]);
82 cnf->app_medias[i] = NULL;
90 * Test if a media exist in the configuration.
91 * @param config The element to work on.
92 * @param pos The index of the media element.
94 int osip_rfc3264_endof_media (struct osip_rfc3264 *config, int pos)
96 if (config==NULL) return -1;
103 * Get a media from the configuration.
104 * @param config The element to work on.
105 * @param pos The index of the media element to get.
107 sdp_media_t *osip_rfc3264_get (struct osip_rfc3264 *config, int pos)
109 if (config==NULL) return NULL;
116 * Remove a media from the configuration.
117 * @param config The element to work on.
118 * @param pos The index of the media element to remove.
120 int osip_rfc3264_remove (struct osip_rfc3264 *config, int pos)
122 if (config==NULL) return -1;
129 * Remove all medias from the configuration.
130 * @param config The element to work on.
132 int osip_rfc3264_reset_media (struct osip_rfc3264 *config)
134 if (config==NULL) return -1;
141 * Add a media (for audio) in the configuration.
142 * @param config The element to work on.
143 * @param pos The index of the media element to add.
145 int osip_rfc3264_add_audio_media (struct osip_rfc3264 *config, sdp_media_t *med, int pos)
147 osip_rfc3264_t *cnf = (osip_rfc3264_t*) config;
148 if (config==NULL) return -1;
149 if (pos>=MAX_AUDIO_CODECS) return -1;
153 for (pos=0;pos<MAX_AUDIO_CODECS && cnf->audio_medias[pos]!=NULL; pos++)
156 if (pos>=MAX_AUDIO_CODECS) return -1; /* no space left */
158 cnf->audio_medias[pos] = med;
164 * Remove a media in the configuration.
165 * @param config The element to work on.
166 * @param pos The index of the media element to remove.
168 int osip_rfc3264_del_audio_media (struct osip_rfc3264 *config, int pos)
170 osip_rfc3264_t *cnf = (osip_rfc3264_t*) config;
171 if (config==NULL) return -1;
172 if (pos>=MAX_AUDIO_CODECS) return -1;
173 sdp_media_free(cnf->audio_medias[pos]);
174 cnf->audio_medias[pos] = NULL;
179 * Add a media (for video) in the configuration.
180 * @param config The element to work on.
181 * @param pos The index of the media element to add.
183 int osip_rfc3264_add_video_media (struct osip_rfc3264 *config, sdp_media_t *med, int pos)
185 osip_rfc3264_t *cnf = (osip_rfc3264_t*) config;
186 if (config==NULL) return -1;
187 if (pos>=MAX_VIDEO_CODECS) return -1;
191 for (pos=0;pos<MAX_VIDEO_CODECS && cnf->video_medias[pos]!=NULL; pos++)
194 if (pos>=MAX_VIDEO_CODECS) return -1; /* no space left */
196 cnf->video_medias[pos] = med;
202 * Remove a media in the configuration.
203 * @param config The element to work on.
204 * @param pos The index of the media element to remove.
206 int osip_rfc3264_del_video_media (struct osip_rfc3264 *config, int pos)
208 osip_rfc3264_t *cnf = (osip_rfc3264_t*) config;
209 if (config==NULL) return -1;
210 if (pos>=MAX_VIDEO_CODECS) return -1;
211 sdp_media_free(cnf->video_medias[pos]);
212 cnf->video_medias[pos] = NULL;
217 * Add a media (for t38) in the configuration.
218 * @param config The element to work on.
219 * @param pos The index of the media element to add.
221 int osip_rfc3264_add_t38_media (struct osip_rfc3264 *config, sdp_media_t *med, int pos)
223 osip_rfc3264_t *cnf = (osip_rfc3264_t*) config;
224 if (config==NULL) return -1;
225 if (pos>=MAX_T38_CODECS) return -1;
229 for (pos=0;pos<MAX_T38_CODECS && cnf->t38_medias[pos]!=NULL; pos++)
232 if (pos>=MAX_T38_CODECS) return -1; /* no space left */
234 cnf->t38_medias[pos] = med;
240 * Remove a media in the configuration.
241 * @param config The element to work on.
242 * @param pos The index of the media element to remove.
244 int osip_rfc3264_del_t38_media (struct osip_rfc3264 *config, int pos)
246 osip_rfc3264_t *cnf = (osip_rfc3264_t*) config;
247 if (config==NULL) return -1;
248 if (pos>=MAX_T38_CODECS) return -1;
249 sdp_media_free(cnf->t38_medias[pos]);
250 cnf->t38_medias[pos] = NULL;
255 * Search for support of a special codec.
256 * @param config The element to work on.
258 sdp_media_t *osip_rfc3264_find_audio (struct osip_rfc3264 *config, char *payload,
261 osip_rfc3264_t *cnf = (osip_rfc3264_t*) config;
263 if (config==NULL) return NULL;
267 for (i=0;i<MAX_AUDIO_CODECS; i++)
269 if (cnf->audio_medias[i]!=NULL)
271 sdp_media_t *med = cnf->audio_medias[i];
272 char *str = (char *) osip_list_get (med->m_payloads, 0);
273 /* static payload?: only compare payload number */
274 if (strlen(str)==strlen(payload)
275 && 0==osip_strcasecmp(str, payload))
282 for (i=0;i<MAX_AUDIO_CODECS; i++)
284 if (cnf->audio_medias[i]!=NULL)
286 sdp_media_t *med = cnf->audio_medias[i];
289 while (!osip_list_eol (med->a_attributes, pos))
291 sdp_attribute_t *attr =
292 (sdp_attribute_t *) osip_list_get (med->a_attributes, pos);
294 if (0==osip_strcasecmp("rtpmap", attr->a_att_field)
295 && attr->a_att_value!=NULL)
297 char *tmp = strchr(attr->a_att_value, ' ');
298 char *tmp2 = strchr(rtpmap, ' ');
299 if (tmp!=NULL && tmp2!=NULL)
301 if (0==osip_strcasecmp(tmp,tmp2))
314 * Search for support of a special codec.
315 * @param config The element to work on.
317 sdp_media_t *osip_rfc3264_find_video (struct osip_rfc3264 *config, char *payload,
320 osip_rfc3264_t *cnf = (osip_rfc3264_t*) config;
322 if (config==NULL) return NULL;
326 for (i=0;i<MAX_VIDEO_CODECS; i++)
328 if (cnf->video_medias[i]!=NULL)
330 sdp_media_t *med = cnf->video_medias[i];
331 char *str = (char *) osip_list_get (med->m_payloads, 0);
332 /* static payload?: only compare payload number */
333 if (strlen(str)==strlen(payload)
334 && 0==osip_strcasecmp(str, payload))
341 for (i=0;i<MAX_VIDEO_CODECS; i++)
343 if (cnf->video_medias[i]!=NULL)
345 sdp_media_t *med = cnf->video_medias[i];
348 while (!osip_list_eol (med->a_attributes, pos))
350 sdp_attribute_t *attr =
351 (sdp_attribute_t *) osip_list_get (med->a_attributes, pos);
353 if (0==osip_strcasecmp("rtpmap", attr->a_att_field)
354 && attr->a_att_value!=NULL)
356 char *tmp = strchr(attr->a_att_value, ' ');
357 char *tmp2 = strchr(rtpmap, ' ');
358 if (tmp!=NULL && tmp2!=NULL)
360 if (0==osip_strcasecmp(tmp,tmp2))
373 * Search for support of a special codec.
374 * @param config The element to work on.
376 sdp_media_t *osip_rfc3264_find_t38 (struct osip_rfc3264 *config, char *payload)
378 osip_rfc3264_t *cnf = (osip_rfc3264_t*) config;
379 if (config==NULL) return NULL;
384 * Search for support of a special codec.
385 * @param config The element to work on.
387 sdp_media_t *osip_rfc3264_find_app (struct osip_rfc3264 *config, char *payload)
389 osip_rfc3264_t *cnf = (osip_rfc3264_t*) config;
390 if (config==NULL) return NULL;
395 * Compare remote sdp packet against local supported media.
396 * Only one media line is checked.
398 * @param config The element to work on.
399 * @param remote_sdp The remote SDP packet.
400 * @param audio_tab The local list of media supported by both side.
401 * @param video_tab The local list of media supported by both side.
402 * @param t38_tab The local list of media supported by both side.
403 * @param app_tab The local list of media supported by both side.
404 * @param pos_media The position of the media line to match.
406 int osip_rfc3264_match(struct osip_rfc3264 *config,
407 sdp_message_t *remote_sdp,
408 sdp_media_t *audio_tab[],
409 sdp_media_t *video_tab[],
410 sdp_media_t *t38_tab[],
411 sdp_media_t *app_tab[],
414 sdp_media_t *remote_med;
422 if (config==NULL) return -1;
425 while (!sdp_message_endof_media (remote_sdp, pos))
429 remote_med = osip_list_get (remote_sdp->m_medias, pos);
430 if (remote_med->m_media!=NULL
431 && 0 == osip_strcasecmp (remote_med->m_media, "audio"))
433 osip_rfc3264_match_audio(config, remote_sdp, remote_med, audio_tab);
435 else if (remote_med->m_media!=NULL
436 && 0 == osip_strcasecmp (remote_med->m_media, "video"))
438 osip_rfc3264_match_video(config, remote_sdp, remote_med, video_tab);
440 else if (remote_med->m_media!=NULL
441 && 0 == osip_strcasecmp (remote_med->m_media, "image"))
443 osip_rfc3264_match_t38(config, remote_sdp, remote_med, t38_tab);
445 else if (remote_med->m_media!=NULL
446 && 0 == osip_strcasecmp (remote_med->m_media, "application"))
448 osip_rfc3264_match_app(config, remote_sdp, remote_med, app_tab);
462 * Compare remote sdp packet against local supported media for audio.
463 * @param config The element to work on.
464 * @param remote_sdp The remote SDP packet.
465 * @param remote_med The remote Media SDP line.
466 * @param audio_tab The local list of media supported by both side.
468 int osip_rfc3264_match_audio(struct osip_rfc3264 *config,
469 sdp_message_t *remote_sdp,
470 sdp_media_t *remote_med,
471 sdp_media_t *audio_tab[])
473 osip_rfc3264_t *cnf = (osip_rfc3264_t*) config;
478 if (cnf==NULL) return -1;
480 /* search for the audio media line */
482 while (!osip_list_eol (remote_med->m_payloads, pos))
484 char *payload = (char *) osip_list_get (remote_med->m_payloads, pos);
485 sdp_media_t *local_med;
489 /* search for the rtpmap associated to the payload */
490 while (!osip_list_eol (remote_med->a_attributes, posattr))
492 sdp_attribute_t *attr =
493 (sdp_attribute_t *) osip_list_get (remote_med->a_attributes, posattr);
494 if (0==osip_strncasecmp(attr->a_att_field, "rtpmap", 6))
496 if (attr->a_att_value!=NULL &&
497 0==osip_strncasecmp(attr->a_att_value, payload, strlen(payload)))
499 /* TODO check if it was not like 101: == 10 */
500 rtpmap = attr->a_att_value;
507 local_med = osip_rfc3264_find_audio(config, payload, rtpmap);
510 /* found a supported codec? */
511 audio_tab[num] = local_med;
515 /* search for support of this codec in local media list */
519 audio_tab[num] = NULL;
524 * Compare remote sdp packet against local supported media for video.
525 * @param config The element to work on.
526 * @param remote_sdp The remote SDP packet.
527 * @param remote_med The remote Media SDP line.
528 * @param video_tab The local list of media supported by both side.
530 int osip_rfc3264_match_video(struct osip_rfc3264 *config,
531 sdp_message_t *remote_sdp,
532 sdp_media_t *remote_med,
533 sdp_media_t *video_tab[])
535 osip_rfc3264_t *cnf = (osip_rfc3264_t*) config;
540 if (cnf==NULL) return -1;
542 /* search for the video media line */
545 while (!osip_list_eol (remote_med->m_payloads, pos))
547 char *payload = (char *) osip_list_get (remote_med->m_payloads, pos);
548 sdp_media_t *local_med;
552 /* search for the rtpmap associated to the payload */
553 while (!osip_list_eol (remote_med->a_attributes, posattr))
555 sdp_attribute_t *attr =
556 (sdp_attribute_t *) osip_list_get (remote_med->a_attributes, posattr);
557 if (0==osip_strncasecmp(attr->a_att_field, "rtpmap", 6))
559 if (attr->a_att_value!=NULL &&
560 0==osip_strncasecmp(attr->a_att_value, payload, strlen(payload)))
562 /* TODO check if it was not like 101: == 10 */
563 rtpmap = attr->a_att_value;
570 local_med = osip_rfc3264_find_video(config, payload, rtpmap);
573 /* found a supported codec? */
574 video_tab[num] = local_med;
578 /* search for support of this codec in local media list */
582 video_tab[num] = NULL;
587 * Compare remote sdp packet against local supported media for t38.
588 * @param config The element to work on.
589 * @param remote_sdp The remote SDP packet.
590 * @param remote_med The remote Media SDP line.
591 * @param t38_tab The local list of media supported by both side.
593 int osip_rfc3264_match_t38(struct osip_rfc3264 *config,
594 sdp_message_t *remote_sdp,
595 sdp_media_t *remote_med,
596 sdp_media_t *t38_tab[])
598 osip_rfc3264_t *cnf = (osip_rfc3264_t*) config;
602 if (cnf==NULL) return -1;
608 * Compare remote sdp packet against local supported media for application.
609 * @param config The element to work on.
610 * @param remote_sdp The remote SDP packet.
611 * @param remote_med The remote Media SDP line.
612 * @param app_tab The local list of media supported by both side.
614 int osip_rfc3264_match_app(struct osip_rfc3264 *config,
615 sdp_message_t *remote_sdp,
616 sdp_media_t *remote_med,
617 sdp_media_t *app_tab[])
619 osip_rfc3264_t *cnf = (osip_rfc3264_t*) config;
623 if (cnf==NULL) return -1;
630 * Prepare an uncomplete answer.
631 * @param config The element to work on.
632 * @param remote_sdp The remote SDP packet.
633 * @param local_sdp The local SDP packet to prepare.
634 * @param length The local SDP packet's length.
636 int osip_rfc3264_prepare_answer(struct osip_rfc3264 *config,
637 sdp_message_t *remote_sdp,
638 char *local_sdp, int length)
641 if (config==NULL) return -1;
642 if (remote_sdp==NULL) return -1;
644 if (osip_list_size(remote_sdp->t_descrs)>0)
646 #if (defined WIN32 || defined _WIN32_WCE)
647 _snprintf(local_sdp, 4096,
649 o=userX 20000001 20000001 IN IP4 TOREPLACE\r\n\
651 c=IN IP4 TOREPLACE\r\n");
653 snprintf(local_sdp, 4096,
655 o=userX 20000001 20000001 IN IP4 TOREPLACE\r\n\
657 c=IN IP4 TOREPLACE\r\n");
659 /* Fill t= (and r=) fields */
661 while (!osip_list_eol(remote_sdp->t_descrs, pos))
664 sdp_time_descr_t *td;
665 td = (sdp_time_descr_t *) osip_list_get(remote_sdp->t_descrs, pos);
666 if (td->t_start_time!=NULL && td->t_stop_time!=NULL)
667 #if (defined WIN32 || defined _WIN32_WCE)
668 _snprintf(tmp, 100, "t=%s %s\r\n", td->t_start_time, td->t_stop_time);
670 snprintf(tmp, 100, "t=%s %s\r\n", td->t_start_time, td->t_stop_time);
673 #if (defined WIN32 || defined _WIN32_WCE)
674 _snprintf(tmp, 100, "t=0 0\r\n");
676 snprintf(tmp, 100, "t=0 0\r\n");
678 if ((int)(strlen(local_sdp)+strlen(tmp)+1)<length)
681 strcat(local_sdp, tmp);
684 while (!osip_list_eol (td->r_repeats, pos2))
686 char *str = (char *) osip_list_get (td->r_repeats, pos2);
688 if ((int)(strlen(local_sdp)+strlen(str)+5+1)<length)
690 strcat(local_sdp, "r=");
691 strcat(local_sdp, str);
692 strcat(local_sdp, "\r\n");
706 while (!osip_list_eol(remote_sdp->m_medias, pos))
714 #if (defined WIN32 || defined _WIN32_WCE)
715 _snprintf(tmp2, 199, "\r\n");
717 snprintf(tmp2, 199, "\r\n");
719 med = (sdp_media_t *) osip_list_get(remote_sdp->m_medias, pos);
721 /* search for the rtpmap associated to the payload */
722 while (!osip_list_eol (med->a_attributes, posattr))
724 sdp_attribute_t *attr =
725 (sdp_attribute_t *) osip_list_get (med->a_attributes, posattr);
726 if (strlen(attr->a_att_field)==8 && attr->a_att_value==NULL)
728 if (0==osip_strncasecmp(attr->a_att_field, "sendonly", 8))
730 #if (defined WIN32 || defined _WIN32_WCE)
731 _snprintf(tmp2, 199, "\r\na=recvonly\r\n");
733 snprintf(tmp2, 199, "\r\na=recvonly\r\n");
737 else if (0==osip_strncasecmp(attr->a_att_field, "recvonly", 8))
739 #if (defined WIN32 || defined _WIN32_WCE)
740 _snprintf(tmp2, 199, "\r\na=sendonly\r\n");
742 snprintf(tmp2, 199, "\r\na=sendonly\r\n");
746 else if (0==osip_strncasecmp(attr->a_att_field, "sendrecv", 8))
750 else if (0==osip_strncasecmp(attr->a_att_field, "inactive", 8))
752 #if (defined WIN32 || defined _WIN32_WCE)
753 _snprintf(tmp2, 199, "\r\na=inactive\r\n");
755 snprintf(tmp2, 199, "\r\na=inactive\r\n");
764 if (med->m_media!=NULL && med->m_proto!=NULL && med->m_number_of_port==NULL)
766 #if (defined WIN32 || defined _WIN32_WCE)
767 _snprintf(tmp, 199, "m=%s %c %s ", med->m_media, inactive, med->m_proto);
769 snprintf(tmp, 199, "m=%s %c %s ", med->m_media, inactive, med->m_proto);
772 else if (med->m_media!=NULL && med->m_proto!=NULL && med->m_number_of_port==NULL)
774 #if (defined WIN32 || defined _WIN32_WCE)
775 _snprintf(tmp, 199, "m=%s %c %s/%s ", med->m_media, inactive, med->m_proto, med->m_number_of_port);
777 snprintf(tmp, 199, "m=%s %c %s/%s ", med->m_media, inactive, med->m_proto, med->m_number_of_port);
783 if ((int)(strlen(local_sdp)+strlen(tmp)+1)<length)
784 strcat(local_sdp, tmp);
787 if ((int)(strlen(local_sdp)+strlen(tmp2)+1)<length)
788 strcat(local_sdp, tmp2);
798 * Agree to support a specific codec.
799 * This method should be called for each codec returned by
800 * osip_rfc3264_match(...) that the calle agree to support.
802 * @param config The element to work on.
803 * @param remote_sdp The remote SDP packet.
804 * @param local_sdp The local SDP packet to complete.
805 * @param med One of the media returned by osip_rfc3264_match.
806 * @param mline The position of the media line to complete.
809 osip_rfc3264_complete_answer(struct osip_rfc3264 *config,
810 sdp_message_t *remote_sdp,
811 sdp_message_t *local_sdp,
815 osip_rfc3264_t *cnf = (osip_rfc3264_t*) config;
816 sdp_media_t *remote_med = NULL;
817 sdp_media_t *local_med = NULL;
819 if (cnf==NULL) return -1;
820 if (remote_sdp==NULL) return -1;
821 if (med==NULL) return -1;
822 if (mline<0) return -1;
823 if (local_sdp==NULL) return -1;
825 while (!osip_list_eol(remote_sdp->m_medias, pos))
827 remote_med = (sdp_media_t *) osip_list_get(remote_sdp->m_medias, pos);
828 local_med = (sdp_media_t *) osip_list_get(local_sdp->m_medias, pos);
829 if (pos==mline) break;
834 if (remote_med==NULL) return -1;
837 while (!osip_list_eol (med->a_attributes, pos))
839 sdp_attribute_t *attr =
840 (sdp_attribute_t *) osip_list_get (med->a_attributes, pos);
842 if (0==osip_strcasecmp("rtpmap", attr->a_att_field)
843 && attr->a_att_value!=NULL)
845 sdp_attribute_t *mattr;
848 /* fill the m= line */
849 tmp = (char*) osip_list_get(med->m_payloads, 0);
851 osip_list_add(local_med->m_payloads, osip_strdup(tmp), -1);
855 sdp_attribute_init(&mattr);
856 mattr->a_att_field = osip_strdup(attr->a_att_field);
857 mattr->a_att_value = osip_strdup(attr->a_att_value);
859 /* fill the a= line */
860 osip_list_add (local_med->a_attributes, mattr, -1);
865 return -1; /* no rtpmap found? It is mandatory in audio and video media */
869 * Agree to support a specific codec.
870 * This method should be called for each codec returned by
871 * osip_rfc3264_match(...)
873 * @param config The element to work on.
874 * @param med One of the media returned by osip_rfc3264_match
875 * @param remote_sdp The remote SDP packet.
876 * @param local_sdp The local SDP packet to prepare.
878 int osip_rfc3264_accept_codec(struct osip_rfc3264 *config,
880 sdp_message_t *remote_sdp,
881 sdp_message_t *local_sdp)
883 if (config==NULL) return -1;
889 /* #ifdef RFC3264_DEBUG */
892 * List supported codecs. (for debugging purpose only)
894 * @param config The element to work on.
896 int __osip_rfc3264_print_codecs(struct osip_rfc3264 *config)
898 osip_rfc3264_t *cnf = (osip_rfc3264_t*) config;
900 if (config==NULL) return -1;
902 fprintf(stdout, "Audio codecs Supported:\n");
903 for (i=0;i<MAX_AUDIO_CODECS; i++)
905 if (cnf->audio_medias[i]!=NULL)
907 sdp_media_t *med = cnf->audio_medias[i];
908 char *str = (char *) osip_list_get (med->m_payloads, 0);
909 fprintf(stdout, "\tm=%s %s %s %s\n",
915 while (!osip_list_eol (med->a_attributes, pos))
917 sdp_attribute_t *attr =
918 (sdp_attribute_t *) osip_list_get (med->a_attributes, pos);
919 fprintf(stdout, "\ta=%s:%s\n",
924 fprintf(stdout, "\n");
928 fprintf(stdout, "Video codecs Supported:\n");
929 for (i=0;i<MAX_VIDEO_CODECS; i++)
931 if (cnf->video_medias[i]!=NULL)
933 sdp_media_t *med = cnf->video_medias[i];
934 char *str = (char *) osip_list_get (med->m_payloads, 0);
935 fprintf(stdout, "\tm=%s %s %s %s\n",
941 while (!osip_list_eol (med->a_attributes, pos))
943 sdp_attribute_t *attr =
944 (sdp_attribute_t *) osip_list_get (med->a_attributes, pos);
945 fprintf(stdout, "\ta=%s:%s\n",
950 fprintf(stdout, "\n");
954 fprintf(stdout, "t38 configs Supported:\n");
955 for (i=0;i<MAX_T38_CODECS; i++)
957 if (cnf->t38_medias[i]!=NULL)
959 sdp_media_t *med = cnf->t38_medias[i];
960 fprintf(stdout, "m=%s %s %s X\n",
965 while (!osip_list_eol (med->a_attributes, pos))
967 sdp_attribute_t *attr =
968 (sdp_attribute_t *) osip_list_get (med->a_attributes, pos);
969 fprintf(stdout, "\ta=%s:%s\n",
974 fprintf(stdout, "\n");
978 fprintf(stdout, "Application config Supported:\n");
979 for (i=0;i<MAX_APP_CODECS; i++)
981 if (cnf->app_medias[i]!=NULL)
983 sdp_media_t *med = cnf->app_medias[i];
984 fprintf(stdout, "m=%s %s %s X\n",
989 while (!osip_list_eol (med->a_attributes, pos))
991 sdp_attribute_t *attr =
992 (sdp_attribute_t *) osip_list_get (med->a_attributes, pos);
993 fprintf(stdout, "\ta=%s:%s\n",
998 fprintf(stdout, "\n");