📄 sdp_negoc.c
字号:
if (tmp == NULL || tmp2 == NULL) return -1; /* no t line?? */ i = sdp_t_time_descr_add (*dest, sgetcopy (tmp), sgetcopy (tmp2)); if (i != 0) return -1; } if (config->fcn_set_attributes != NULL) config->fcn_set_attributes (con, *dest, -1); return 0;}intsdp_confirm_media (sdp_context_t * context, sdp_t * remote, sdp_t ** dest){ char *payload; char *tmp, *tmp2, *tmp3, *tmp4; int ret; int i; int k; int audio_qty = 0; /* accepted audio line: do not accept more than one */ int video_qty = 0; i = 0; while (!sdp_endof_media (remote, i)) { tmp = sdp_m_media_get (remote, i); tmp2 = sdp_m_port_get (remote, i); tmp3 = sdp_m_number_of_port_get (remote, i); tmp4 = sdp_m_proto_get (remote, i); if (tmp == NULL) return -1; sdp_m_media_add (*dest, sgetcopy (tmp), sgetcopy ("0"), NULL, sgetcopy (tmp4)); k = 0; if (0 == strncmp (tmp, "audio", 5)) { do { payload = sdp_m_payload_get (remote, i, k); if (payload != NULL) { payload_t *my_payload = sdp_config_find_audio_payload (payload); if (my_payload != NULL) /* payload is supported */ { ret = -1; /* somtimes, codec can be refused even if supported */ if (config->fcn_accept_audio_codec != NULL) ret = config->fcn_accept_audio_codec (context, tmp2, tmp3, audio_qty, payload); if (0 == ret) { sdp_m_payload_add (*dest, i, sgetcopy (payload)); if (my_payload->a_rtpmap != NULL) sdp_a_attribute_add (*dest, i, sgetcopy ("rtpmap"), sgetcopy (my_payload-> a_rtpmap)); if (my_payload->c_nettype != NULL) { sdp_media_t *med = list_get ((*dest)->m_medias, i); if (list_eol (med->c_connections, 0)) sdp_c_connection_add (*dest, i, sgetcopy (my_payload-> c_nettype), sgetcopy (my_payload-> c_addrtype), sgetcopy (my_payload-> c_addr), sgetcopy (my_payload-> c_addr_multicast_ttl), sgetcopy (my_payload-> c_addr_multicast_int)); } } } } k++; } while (payload != NULL); if (NULL != sdp_m_payload_get (*dest, i, 0)) audio_qty = 1; } else if (0 == strncmp (tmp, "video", 5)) { do { payload = sdp_m_payload_get (remote, i, k); if (payload != NULL) { payload_t *my_payload = sdp_config_find_video_payload (payload); if (my_payload != NULL) /* payload is supported */ { ret = -1; if (config->fcn_accept_video_codec != NULL) ret = config->fcn_accept_video_codec (context, tmp2, tmp3, video_qty, payload); if (0 == ret) { sdp_m_payload_add (*dest, i, sgetcopy (payload)); /* TODO set the attribute list (rtpmap..) */ if (my_payload->a_rtpmap != NULL) sdp_a_attribute_add (*dest, i, sgetcopy ("rtpmap"), sgetcopy (my_payload-> a_rtpmap)); if (my_payload->c_nettype != NULL) { sdp_media_t *med = list_get ((*dest)->m_medias, i); if (list_eol (med->c_connections, 0)) sdp_c_connection_add (*dest, i, sgetcopy (my_payload-> c_nettype), sgetcopy (my_payload-> c_addrtype), sgetcopy (my_payload-> c_addr), sgetcopy (my_payload-> c_addr_multicast_ttl), sgetcopy (my_payload-> c_addr_multicast_int)); } } } } k++; } while (payload != NULL); if (NULL != sdp_m_payload_get (*dest, i, 0)) video_qty = 1; } else { do { payload = sdp_m_payload_get (remote, i, k); if (payload != NULL) { payload_t *my_payload = sdp_config_find_other_payload (payload); if (my_payload != NULL) /* payload is supported */ { ret = -1; if (config->fcn_accept_other_codec != NULL) ret = config->fcn_accept_other_codec (context, tmp, tmp2, tmp3, payload); if (0 == ret) { sdp_m_payload_add (*dest, i, sgetcopy (payload)); /* rtpmap has no meaning here! */ if (my_payload->c_nettype != NULL) { sdp_media_t *med = list_get ((*dest)->m_medias, i); if (list_eol (med->c_connections, 0)) sdp_c_connection_add (*dest, i, sgetcopy (my_payload-> c_nettype), sgetcopy (my_payload-> c_addrtype), sgetcopy (my_payload-> c_addr), sgetcopy (my_payload-> c_addr_multicast_ttl), sgetcopy (my_payload-> c_addr_multicast_int)); } } } } k++; } while (payload != NULL); } i++; } return 0;}intsdp_context_execute_negociation (sdp_context_t * context){ int m_lines_that_match = 0; sdp_t *remote; sdp_t *local; int i; if (context == NULL) return -1; remote = context->remote; if (remote == NULL) return -1; i = sdp_init (&local); if (i != 0) return -1; if (0 != strncmp (remote->v_version, "0", 1)) { sdp_free (local); sfree (local); /* sdp_context->fcn_wrong_version(context); */ return 406; /* Not Acceptable */ } i = sdp_partial_clone (context, remote, &local); if (i != 0) { sdp_free (local); sfree (local); return -1; } i = sdp_confirm_media (context, remote, &local); if (i != 0) { sdp_free (local); sfree (local); return i; } i = 0; while (!sdp_endof_media (local, i)) { /* this is to refuse each line with no codec that matches! */ if (NULL == sdp_m_payload_get (local, i, 0)) { sdp_media_t *med = list_get ((local)->m_medias, i); char *str = sdp_m_payload_get (remote, i, 0); sdp_m_payload_add (local, i, sgetcopy (str)); sfree (med->m_port); med->m_port = sgetcopy ("0"); /* refuse this line */ } else { /* number of "m" lines that match */ sdp_media_t *med = list_get (local->m_medias, i); m_lines_that_match++; sfree (med->m_port); /* AMD: use the correct fcn_get_xxx_port method: */ if (0 == strcmp (med->m_media, "audio")) { if (config->fcn_get_audio_port != NULL) med->m_port = config->fcn_get_audio_port (context, i); else med->m_port = sgetcopy ("0"); /* should never happen */ } else if (0 == strcmp (med->m_media, "video")) { if (config->fcn_get_video_port != NULL) med->m_port = config->fcn_get_video_port (context, i); else med->m_port = sgetcopy ("0"); /* should never happen */ } else { if (config->fcn_get_other_port != NULL) med->m_port = config->fcn_get_other_port (context, i); else med->m_port = sgetcopy ("0"); /* should never happen */ } } i++; } if (m_lines_that_match > 0) { context->local = local; return 200; } else { sdp_free (local); sfree (local); return 415; }}intsdp_build_offer (sdp_context_t * con, sdp_t ** sdp, char *audio_port, char *video_port){ int i; int media_line = 0; i = sdp_init (sdp); if (i != 0) return -1; sdp_v_version_set (*sdp, sgetcopy ("0")); /* those fields MUST be set */ sdp_o_origin_set (*sdp, sgetcopy (config->o_username), sgetcopy (config->o_session_id), sgetcopy (config->o_session_version), sgetcopy (config->o_nettype), sgetcopy (config->o_addrtype), sgetcopy (config->o_addr)); sdp_s_name_set (*sdp, sgetcopy ("A call")); if (config->fcn_set_info != NULL) config->fcn_set_info (con, *sdp); if (config->fcn_set_uri != NULL) config->fcn_set_uri (con, *sdp); if (config->fcn_set_emails != NULL) config->fcn_set_emails (con, *sdp); if (config->fcn_set_phones != NULL) config->fcn_set_phones (con, *sdp); if (config->c_nettype != NULL) sdp_c_connection_add (*sdp, -1, sgetcopy (config->c_nettype), sgetcopy (config->c_addrtype), sgetcopy (config->c_addr), sgetcopy (config->c_addr_multicast_ttl), sgetcopy (config->c_addr_multicast_int)); { /* offer-answer draft says we must copy the "t=" line */ int now = time (NULL); char *tmp = smalloc (15); char *tmp2 = smalloc (15); sprintf (tmp, "%i", now); sprintf (tmp2, "%i", now + 3600); i = sdp_t_time_descr_add (*sdp, tmp, tmp2); if (i != 0) return -1; } if (config->fcn_set_attributes != NULL) config->fcn_set_attributes (con, *sdp, -1); /* add all audio codec */ if (!list_eol (config->audio_codec, 0)) { int pos = 0; payload_t *my = (payload_t *) list_get (config->audio_codec, pos); /* all media MUST have the same PROTO, PORT. */ sdp_m_media_add (*sdp, sgetcopy ("audio"), sgetcopy (audio_port), my->number_of_port, sgetcopy (my->proto)); while (!list_eol (config->audio_codec, pos)) { my = (payload_t *) list_get (config->audio_codec, pos); sdp_m_payload_add (*sdp, media_line, sgetcopy (my->payload)); if (my->a_rtpmap != NULL) sdp_a_attribute_add (*sdp, media_line, sgetcopy ("rtpmap"), sgetcopy (my->a_rtpmap)); pos++; } media_line++; } /* add all video codec */ if (!list_eol (config->video_codec, 0)) { int pos = 0; payload_t *my = (payload_t *) list_get (config->video_codec, pos); /* all media MUST have the same PROTO, PORT. */ sdp_m_media_add (*sdp, sgetcopy ("video"), sgetcopy (video_port), my->number_of_port, sgetcopy (my->proto)); while (!list_eol (config->video_codec, pos)) { my = (payload_t *) list_get (config->video_codec, pos); sdp_m_payload_add (*sdp, media_line, sgetcopy (my->payload)); if (my->a_rtpmap != NULL) sdp_a_attribute_add (*sdp, media_line, sgetcopy ("rtpmap"), sgetcopy (my->a_rtpmap)); pos++; } media_line++; } return 0;}/* build the SDP packet with only one audio codec and one video codec. * - Usefull if you don't want to restrict proposal to one codec only - * - Limitation, only one codec will be proposed */int__sdp_build_offer (sdp_context_t * con, sdp_t ** sdp, char *audio_port, char *video_port, char *audio_codec, char *video_codec){ int i; int media_line = 0; i = sdp_init (sdp); if (i != 0) return -1; sdp_v_version_set (*sdp, sgetcopy ("0")); /* those fields MUST be set */ sdp_o_origin_set (*sdp, sgetcopy (config->o_username), sgetcopy (config->o_session_id), sgetcopy (config->o_session_version), sgetcopy (config->o_nettype), sgetcopy (config->o_addrtype), sgetcopy (config->o_addr)); sdp_s_name_set (*sdp, sgetcopy ("A call")); if (config->fcn_set_info != NULL) config->fcn_set_info (con, *sdp); if (config->fcn_set_uri != NULL) config->fcn_set_uri (con, *sdp); if (config->fcn_set_emails != NULL) config->fcn_set_emails (con, *sdp); if (config->fcn_set_phones != NULL) config->fcn_set_phones (con, *sdp); if (config->c_nettype != NULL) sdp_c_connection_add (*sdp, -1, sgetcopy (config->c_nettype), sgetcopy (config->c_addrtype), sgetcopy (config->c_addr), sgetcopy (config->c_addr_multicast_ttl), sgetcopy (config->c_addr_multicast_int)); { /* offer-answer draft says we must copy the "t=" line */ int now = time (NULL); char *tmp = smalloc (15); char *tmp2 = smalloc (15); sprintf (tmp, "%i", now); sprintf (tmp2, "%i", now + 3600); i = sdp_t_time_descr_add (*sdp, tmp, tmp2); if (i != 0) return -1; } if (config->fcn_set_attributes != NULL) config->fcn_set_attributes (con, *sdp, -1); /* add all audio codec */ if (audio_codec!=NULL) { if (!list_eol (config->audio_codec, 0)) { int pos = 0; payload_t *my = (payload_t *) list_get (config->audio_codec, pos); while (!list_eol (config->audio_codec, pos)) { my = (payload_t *) list_get (config->audio_codec, pos); if (0==strcmp(audio_codec, my->payload)) { /* all media MUST have the same PROTO, PORT. */ sdp_m_media_add (*sdp, sgetcopy ("audio"), sgetcopy (audio_port), my->number_of_port, sgetcopy (my->proto)); sdp_m_payload_add (*sdp, media_line, sgetcopy (my->payload)); if (my->a_rtpmap != NULL) sdp_a_attribute_add (*sdp, media_line, sgetcopy ("rtpmap"), sgetcopy (my->a_rtpmap)); media_line++; break; } pos++; } } } /* add all video codec */ if (video_codec!=NULL) { if (!list_eol (config->video_codec, 0)) { int pos = 0; payload_t *my = (payload_t *) list_get (config->video_codec, pos); while (!list_eol (config->video_codec, pos)) { my = (payload_t *) list_get (config->video_codec, pos); if (0==strcmp(video_codec, my->payload)) { /* all media MUST have the same PROTO, PORT. */ sdp_m_media_add (*sdp, sgetcopy ("video"), sgetcopy (video_port), my->number_of_port, sgetcopy (my->proto)); sdp_m_payload_add (*sdp, media_line, sgetcopy (my->payload)); if (my->a_rtpmap != NULL) sdp_a_attribute_add (*sdp, media_line, sgetcopy ("rtpmap"), sgetcopy (my->a_rtpmap)); media_line++; break; } pos++; } } } return 0;}intsdp_put_on_hold (sdp_t * sdp){ int pos; int pos_media = -1; char *rcvsnd; int recv_send = -1; pos = 0; rcvsnd = sdp_a_att_field_get (sdp, pos_media, pos); while (rcvsnd != NULL) { if (rcvsnd != NULL && 0 == strcmp (rcvsnd, "sendonly") && 0 == strcmp (rcvsnd, "sendrecv")) { recv_send = 0; } else if (rcvsnd != NULL && 0 == strcmp (rcvsnd, "recvonly")) { recv_send = 0; sprintf (rcvsnd, "sendonly"); } pos++; rcvsnd = sdp_a_att_field_get (sdp, pos_media, pos); } pos_media = 0; while (!sdp_endof_media (sdp, pos_media)) { pos = 0; rcvsnd = sdp_a_att_field_get (sdp, pos_media, pos); while (rcvsnd != NULL) { if (rcvsnd != NULL && 0 == strcmp (rcvsnd, "sendonly")) { recv_send = 0; } else if (rcvsnd != NULL && 0 == strcmp (rcvsnd, "recvonly")) { recv_send = 0; sprintf (rcvsnd, "sendonly"); } pos++; rcvsnd = sdp_a_att_field_get (sdp, pos_media, pos); } pos_media++; } if (recv_send == -1) { /* we need to add a global attribute with a feild set to "sendonly" */ sdp_a_attribute_add (sdp, -1, sgetcopy ("sendonly"), NULL); } return 0;}intsdp_put_off_hold (sdp_t * sdp){ int pos; int pos_media = -1; char *rcvsnd; pos = 0; rcvsnd = sdp_a_att_field_get (sdp, pos_media, pos); while (rcvsnd != NULL) { if (rcvsnd != NULL && (0 == strcmp (rcvsnd, "sendonly") || 0 == strcmp (rcvsnd, "recvonly"))) { sprintf (rcvsnd, "sendrecv"); } pos++; rcvsnd = sdp_a_att_field_get (sdp, pos_media, pos); } pos_media = 0; while (!sdp_endof_media (sdp, pos_media)) { pos = 0; rcvsnd = sdp_a_att_field_get (sdp, pos_media, pos); while (rcvsnd != NULL) { if (rcvsnd != NULL && (0 == strcmp (rcvsnd, "sendonly") || 0 == strcmp (rcvsnd, "recvonly"))) { sprintf (rcvsnd, "sendrecv"); } pos++; rcvsnd = sdp_a_att_field_get (sdp, pos_media, pos); } pos_media++; } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -