📄 osip_rfc3264.c
字号:
/* The oSIP library implements the Session Initiation Protocol (SIP -rfc3261-) Copyright (C) 2001,2002,2003 Aymeric MOIZARD jack@atosc.org This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*/#include <stdlib.h>#include <osipparser2/osip_port.h>#include <osipparser2/osip_rfc3264.h>#include <osip_rfc3264i.h> /* internal include *//** * Initialize negotiation facility.. * @param config The element to work on. */int osip_rfc3264_init (struct osip_rfc3264 **config){ osip_rfc3264_t *cnf; *config = NULL; cnf = (osip_rfc3264_t *) osip_malloc (sizeof(osip_rfc3264_t)); if (cnf==NULL) return -1; memset(cnf, 0, sizeof(osip_rfc3264_t)); *config = cnf; return 0;}/** * Free negotiation facility. * @param config The element to work on. */void osip_rfc3264_free (struct osip_rfc3264 *config){ osip_rfc3264_t *cnf = (osip_rfc3264_t*) config; int i; if (config==NULL) return; for (i=0;i<MAX_AUDIO_CODECS; i++) { if (cnf->audio_medias[i]!=NULL) { sdp_media_free(cnf->audio_medias[i]); cnf->audio_medias[i] = NULL; } } for (i=0;i<MAX_VIDEO_CODECS; i++) { if (cnf->video_medias[i]!=NULL) { sdp_media_free(cnf->video_medias[i]); cnf->video_medias[i] = NULL; } } for (i=0;i<MAX_T38_CODECS; i++) { if (cnf->t38_medias[i]!=NULL) { sdp_media_free(cnf->t38_medias[i]); cnf->t38_medias[i] = NULL; } } for (i=0;i<MAX_APP_CODECS; i++) { if (cnf->app_medias[i]!=NULL) { sdp_media_free(cnf->app_medias[i]); cnf->app_medias[i] = NULL; } } osip_free(cnf);}/** * Test if a media exist in the configuration. * @param config The element to work on. * @param pos The index of the media element. */int osip_rfc3264_endof_media (struct osip_rfc3264 *config, int pos){ if (config==NULL) return -1; return 0;}/** * Get a media from the configuration. * @param config The element to work on. * @param pos The index of the media element to get. */sdp_media_t *osip_rfc3264_get (struct osip_rfc3264 *config, int pos){ if (config==NULL) return NULL; return NULL;}/** * Remove a media from the configuration. * @param config The element to work on. * @param pos The index of the media element to remove. */int osip_rfc3264_remove (struct osip_rfc3264 *config, int pos){ if (config==NULL) return -1; return 0;}/** * Remove all medias from the configuration. * @param config The element to work on. */int osip_rfc3264_reset_media (struct osip_rfc3264 *config){ if (config==NULL) return -1; return 0;}/** * Add a media (for audio) in the configuration. * @param config The element to work on. * @param pos The index of the media element to add. */int osip_rfc3264_add_audio_media (struct osip_rfc3264 *config, sdp_media_t *med, int pos){ osip_rfc3264_t *cnf = (osip_rfc3264_t*) config; if (config==NULL) return -1; if (pos>=MAX_AUDIO_CODECS) return -1; if (pos==-1) { for (pos=0;pos<MAX_AUDIO_CODECS && cnf->audio_medias[pos]!=NULL; pos++) { } } if (pos>=MAX_AUDIO_CODECS) return -1; /* no space left */ cnf->audio_medias[pos] = med; return 0;}/** * Remove a media in the configuration. * @param config The element to work on. * @param pos The index of the media element to remove. */int osip_rfc3264_del_audio_media (struct osip_rfc3264 *config, int pos){ osip_rfc3264_t *cnf = (osip_rfc3264_t*) config; if (config==NULL) return -1; if (pos>=MAX_AUDIO_CODECS) return -1; sdp_media_free(cnf->audio_medias[pos]); cnf->audio_medias[pos] = NULL; return 0;}/** * Add a media (for video) in the configuration. * @param config The element to work on. * @param pos The index of the media element to add. */int osip_rfc3264_add_video_media (struct osip_rfc3264 *config, sdp_media_t *med, int pos){ osip_rfc3264_t *cnf = (osip_rfc3264_t*) config; if (config==NULL) return -1; if (pos>=MAX_VIDEO_CODECS) return -1; if (pos==-1) { for (pos=0;pos<MAX_VIDEO_CODECS && cnf->video_medias[pos]!=NULL; pos++) { } } if (pos>=MAX_VIDEO_CODECS) return -1; /* no space left */ cnf->video_medias[pos] = med; return 0;}/** * Remove a media in the configuration. * @param config The element to work on. * @param pos The index of the media element to remove. */int osip_rfc3264_del_video_media (struct osip_rfc3264 *config, int pos){ osip_rfc3264_t *cnf = (osip_rfc3264_t*) config; if (config==NULL) return -1; if (pos>=MAX_VIDEO_CODECS) return -1; sdp_media_free(cnf->video_medias[pos]); cnf->video_medias[pos] = NULL; return 0;}/** * Add a media (for t38) in the configuration. * @param config The element to work on. * @param pos The index of the media element to add. */int osip_rfc3264_add_t38_media (struct osip_rfc3264 *config, sdp_media_t *med, int pos){ osip_rfc3264_t *cnf = (osip_rfc3264_t*) config; if (config==NULL) return -1; if (pos>=MAX_T38_CODECS) return -1; if (pos==-1) { for (pos=0;pos<MAX_T38_CODECS && cnf->t38_medias[pos]!=NULL; pos++) { } } if (pos>=MAX_T38_CODECS) return -1; /* no space left */ cnf->t38_medias[pos] = med; return 0;}/** * Remove a media in the configuration. * @param config The element to work on. * @param pos The index of the media element to remove. */int osip_rfc3264_del_t38_media (struct osip_rfc3264 *config, int pos){ osip_rfc3264_t *cnf = (osip_rfc3264_t*) config; if (config==NULL) return -1; if (pos>=MAX_T38_CODECS) return -1; sdp_media_free(cnf->t38_medias[pos]); cnf->t38_medias[pos] = NULL; return 0;}/** * Search for support of a special codec. * @param config The element to work on. */ sdp_media_t *osip_rfc3264_find_audio (struct osip_rfc3264 *config, char *payload, char *rtpmap){ osip_rfc3264_t *cnf = (osip_rfc3264_t*) config; int i; if (config==NULL) return NULL; if (rtpmap==NULL) { for (i=0;i<MAX_AUDIO_CODECS; i++) { if (cnf->audio_medias[i]!=NULL) { sdp_media_t *med = cnf->audio_medias[i]; char *str = (char *) osip_list_get (med->m_payloads, 0); /* static payload?: only compare payload number */ if (strlen(str)==strlen(payload) && 0==osip_strcasecmp(str, payload)) return med; } } return NULL; } for (i=0;i<MAX_AUDIO_CODECS; i++) { if (cnf->audio_medias[i]!=NULL) { sdp_media_t *med = cnf->audio_medias[i]; int pos = 0; while (!osip_list_eol (med->a_attributes, pos)) { sdp_attribute_t *attr = (sdp_attribute_t *) osip_list_get (med->a_attributes, pos); if (0==osip_strcasecmp("rtpmap", attr->a_att_field) && attr->a_att_value!=NULL) { char *tmp = strchr(attr->a_att_value, ' '); char *tmp2 = strchr(rtpmap, ' '); if (tmp!=NULL && tmp2!=NULL) { if (0==osip_strcasecmp(tmp,tmp2)) return med; } } pos++; } } } return NULL;}/** * Search for support of a special codec. * @param config The element to work on. */ sdp_media_t *osip_rfc3264_find_video (struct osip_rfc3264 *config, char *payload, char *rtpmap){ osip_rfc3264_t *cnf = (osip_rfc3264_t*) config; int i; if (config==NULL) return NULL; if (rtpmap==NULL) { for (i=0;i<MAX_VIDEO_CODECS; i++) { if (cnf->video_medias[i]!=NULL) { sdp_media_t *med = cnf->video_medias[i]; char *str = (char *) osip_list_get (med->m_payloads, 0); /* static payload?: only compare payload number */ if (strlen(str)==strlen(payload) && 0==osip_strcasecmp(str, payload)) return med; } } return NULL; } for (i=0;i<MAX_VIDEO_CODECS; i++) { if (cnf->video_medias[i]!=NULL) { sdp_media_t *med = cnf->video_medias[i]; int pos = 0; while (!osip_list_eol (med->a_attributes, pos)) { sdp_attribute_t *attr = (sdp_attribute_t *) osip_list_get (med->a_attributes, pos); if (0==osip_strcasecmp("rtpmap", attr->a_att_field) && attr->a_att_value!=NULL) { char *tmp = strchr(attr->a_att_value, ' '); char *tmp2 = strchr(rtpmap, ' '); if (tmp!=NULL && tmp2!=NULL) { if (0==osip_strcasecmp(tmp,tmp2)) return med; } } pos++; } } } return NULL;}/** * Search for support of a special codec. * @param config The element to work on. */ sdp_media_t *osip_rfc3264_find_t38 (struct osip_rfc3264 *config, char *payload){ osip_rfc3264_t *cnf = (osip_rfc3264_t*) config; if (config==NULL) return NULL; return NULL;}/** * Search for support of a special codec. * @param config The element to work on. */ sdp_media_t *osip_rfc3264_find_app (struct osip_rfc3264 *config, char *payload){ osip_rfc3264_t *cnf = (osip_rfc3264_t*) config; if (config==NULL) return NULL; return NULL;}/** * Compare remote sdp packet against local supported media. * Only one media line is checked. * * @param config The element to work on. * @param remote_sdp The remote SDP packet. * @param audio_tab The local list of media supported by both side. * @param video_tab The local list of media supported by both side. * @param t38_tab The local list of media supported by both side. * @param app_tab The local list of media supported by both side. * @param pos_media The position of the media line to match. */int osip_rfc3264_match(struct osip_rfc3264 *config, sdp_message_t *remote_sdp, sdp_media_t *audio_tab[], sdp_media_t *video_tab[], sdp_media_t *t38_tab[], sdp_media_t *app_tab[], int pos_media){ sdp_media_t *remote_med; int pos; audio_tab[0] = NULL; video_tab[0] = NULL; t38_tab[0] = NULL; app_tab[0] = NULL; if (config==NULL) return -1; pos=0; while (!sdp_message_endof_media (remote_sdp, pos)) { if (pos_media==0) { remote_med = osip_list_get (remote_sdp->m_medias, pos); if (remote_med->m_media!=NULL && 0 == osip_strcasecmp (remote_med->m_media, "audio")) { osip_rfc3264_match_audio(config, remote_sdp, remote_med, audio_tab); } else if (remote_med->m_media!=NULL && 0 == osip_strcasecmp (remote_med->m_media, "video")) { osip_rfc3264_match_video(config, remote_sdp, remote_med, video_tab); } else if (remote_med->m_media!=NULL && 0 == osip_strcasecmp (remote_med->m_media, "image")) { osip_rfc3264_match_t38(config, remote_sdp, remote_med, t38_tab); } else if (remote_med->m_media!=NULL && 0 == osip_strcasecmp (remote_med->m_media, "application")) { osip_rfc3264_match_app(config, remote_sdp, remote_med, app_tab); } return 0; } remote_med=NULL; pos++; pos_media--; } return -1;}/** * Compare remote sdp packet against local supported media for audio. * @param config The element to work on. * @param remote_sdp The remote SDP packet. * @param remote_med The remote Media SDP line. * @param audio_tab The local list of media supported by both side. */int osip_rfc3264_match_audio(struct osip_rfc3264 *config, sdp_message_t *remote_sdp, sdp_media_t *remote_med, sdp_media_t *audio_tab[]){ osip_rfc3264_t *cnf = (osip_rfc3264_t*) config; int num=0; int pos; audio_tab[0] = NULL; if (cnf==NULL) return -1; /* search for the audio media line */ pos=0; while (!osip_list_eol (remote_med->m_payloads, pos)) { char *payload = (char *) osip_list_get (remote_med->m_payloads, pos); sdp_media_t *local_med; char *rtpmap = NULL; int posattr = 0; /* search for the rtpmap associated to the payload */ while (!osip_list_eol (remote_med->a_attributes, posattr)) { sdp_attribute_t *attr = (sdp_attribute_t *) osip_list_get (remote_med->a_attributes, posattr); if (0==osip_strncasecmp(attr->a_att_field, "rtpmap", 6)) { if (attr->a_att_value!=NULL && 0==osip_strncasecmp(attr->a_att_value, payload, strlen(payload))) { /* TODO check if it was not like 101: == 10 */ rtpmap = attr->a_att_value; break; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -