diff --git a/include/asterisk/res_pjsip.h b/include/asterisk/res_pjsip.h index ac4725eb72..9f353936ca 100644 --- a/include/asterisk/res_pjsip.h +++ b/include/asterisk/res_pjsip.h @@ -953,6 +953,40 @@ struct ast_sip_endpoint { #define AST_SIP_X_AST_TXP "x-ast-txp" #define AST_SIP_X_AST_TXP_LEN 9 +/*! Common media types used throughout res_pjsip and pjproject */ +extern pjsip_media_type pjsip_media_type_application_json; +extern pjsip_media_type pjsip_media_type_application_media_control_xml; +extern pjsip_media_type pjsip_media_type_application_pidf_xml; +extern pjsip_media_type pjsip_media_type_application_xpidf_xml; +extern pjsip_media_type pjsip_media_type_application_cpim_xpidf_xml; +extern pjsip_media_type pjsip_media_type_application_rlmi_xml; +extern pjsip_media_type pjsip_media_type_application_simple_message_summary; +extern pjsip_media_type pjsip_media_type_application_sdp; +extern pjsip_media_type pjsip_media_type_multipart_alternative; +extern pjsip_media_type pjsip_media_type_multipart_mixed; +extern pjsip_media_type pjsip_media_type_multipart_related; +extern pjsip_media_type pjsip_media_type_text_plain; + +/*! + * \brief Compare pjsip media types + * + * \param pjsip_media_type a + * \param pjsip_media_type b + * \retval 1 Media types are equal + * \retval 0 Media types are not equal + */ +int ast_sip_are_media_types_equal(pjsip_media_type *a, pjsip_media_type *b); + +/*! + * \brief Check if a media type is in a list of others + * + * \param a pjsip_media_type to search for + * \param ... one or more pointers to pjsip_media_types the last of which must be "SENTINEL" + * \retval 1 Media types are equal + * \retval 0 Media types are not equal + */ +int ast_sip_is_media_type_in(pjsip_media_type *a, ...) attribute_sentinel; + /*! * \brief Initialize an auth vector with the configured values. * diff --git a/res/res_pjsip.c b/res/res_pjsip.c index 697767d2b8..2f9edfb930 100644 --- a/res/res_pjsip.c +++ b/res/res_pjsip.c @@ -5292,6 +5292,34 @@ int ast_copy_pj_str2(char **dest, const pj_str_t *src) return res; } +int ast_sip_are_media_types_equal(pjsip_media_type *a, pjsip_media_type *b) +{ + int rc = 0; + if (a != NULL && b != NULL) { + rc = pjsip_media_type_cmp(a, b, 0) ? 0 : 1; + } + return rc; +} + +int ast_sip_is_media_type_in(pjsip_media_type *a, ...) +{ + int rc = 0; + pjsip_media_type *b = NULL; + va_list ap; + + ast_assert(a != NULL); + va_start(ap, a); + + while ((b = va_arg(ap, pjsip_media_type *)) != (pjsip_media_type *)SENTINEL) { + if (pjsip_media_type_cmp(a, b, 0) == 0) { + rc = 1; + break; + } + } + va_end(ap); + + return rc; +} int ast_sip_is_content_type(pjsip_media_type *content_type, char *type, char *subtype) { @@ -5844,6 +5872,20 @@ void never_called_res_pjsip(void) pjmedia_strerror(0, NULL, 0); } +/* Definitions of media types declared "extern" in res_pjsip.h */ +pjsip_media_type pjsip_media_type_application_json; +pjsip_media_type pjsip_media_type_application_media_control_xml; +pjsip_media_type pjsip_media_type_application_pidf_xml; +pjsip_media_type pjsip_media_type_application_xpidf_xml; +pjsip_media_type pjsip_media_type_application_cpim_xpidf_xml; +pjsip_media_type pjsip_media_type_application_rlmi_xml; +pjsip_media_type pjsip_media_type_application_simple_message_summary; +pjsip_media_type pjsip_media_type_application_sdp; +pjsip_media_type pjsip_media_type_multipart_alternative; +pjsip_media_type pjsip_media_type_multipart_mixed; +pjsip_media_type pjsip_media_type_multipart_related; +pjsip_media_type pjsip_media_type_text_plain; + static int load_module(void) { struct ast_threadpool_options options; @@ -5863,6 +5905,21 @@ static int load_module(void) ast_log(LOG_WARNING, "Failed to register pjmedia error codes. Codes will not be decoded.\n"); } + /* Initialize common media types */ + pjsip_media_type_init2(&pjsip_media_type_application_json, "application", "json"); + pjsip_media_type_init2(&pjsip_media_type_application_media_control_xml, "application", "media_control+xml"); + pjsip_media_type_init2(&pjsip_media_type_application_pidf_xml, "application", "pidf+xml"); + pjsip_media_type_init2(&pjsip_media_type_application_xpidf_xml, "application", "xpidf+xml"); + pjsip_media_type_init2(&pjsip_media_type_application_cpim_xpidf_xml, "application", "cpim-xpidf+xml"); + pjsip_media_type_init2(&pjsip_media_type_application_rlmi_xml, "application", "rlmi+xml"); + pjsip_media_type_init2(&pjsip_media_type_application_sdp, "application", "sdp"); + pjsip_media_type_init2(&pjsip_media_type_application_simple_message_summary, "application", "simple-message-summary"); + pjsip_media_type_init2(&pjsip_media_type_multipart_alternative, "multipart", "alternative"); + pjsip_media_type_init2(&pjsip_media_type_multipart_mixed, "multipart", "mixed"); + pjsip_media_type_init2(&pjsip_media_type_multipart_related, "multipart", "related"); + pjsip_media_type_init2(&pjsip_media_type_text_plain, "text", "plain"); + + if (ast_sip_initialize_system()) { ast_log(LOG_ERROR, "Failed to initialize SIP 'system' configuration section. Aborting load\n"); goto error; diff --git a/res/res_pjsip.exports.in b/res/res_pjsip.exports.in index 7ac2b7e83a..58868e398f 100644 --- a/res/res_pjsip.exports.in +++ b/res/res_pjsip.exports.in @@ -2,6 +2,7 @@ global: LINKER_SYMBOL_PREFIXast_sip_*; LINKER_SYMBOL_PREFIX__ast_sip_*; + LINKER_SYMBOL_PREFIXpjsip_media_type_*; LINKER_SYMBOL_PREFIXast_copy_pj_str; LINKER_SYMBOL_PREFIXast_copy_pj_str2; LINKER_SYMBOL_PREFIXast_pjsip_rdata_get_endpoint; diff --git a/res/res_pjsip_sdp_rtp.c b/res/res_pjsip_sdp_rtp.c index 10db010856..a5e0b78c72 100644 --- a/res/res_pjsip_sdp_rtp.c +++ b/res/res_pjsip_sdp_rtp.c @@ -2317,9 +2317,8 @@ static int video_info_incoming_request(struct ast_sip_session *session, struct p pjsip_tx_data *tdata; if (!session->channel - || !ast_sip_is_content_type(&rdata->msg_info.msg->body->content_type, - "application", - "media_control+xml")) { + || !ast_sip_are_media_types_equal(&rdata->msg_info.msg->body->content_type, + &pjsip_media_type_application_media_control_xml)) { return 0; } diff --git a/res/res_pjsip_session.c b/res/res_pjsip_session.c index e91542929d..cfd71fb576 100644 --- a/res/res_pjsip_session.c +++ b/res/res_pjsip_session.c @@ -3893,9 +3893,8 @@ static int check_content_disposition(pjsip_rx_data *rdata) pjsip_ctype_hdr *ctype_hdr = rdata->msg_info.ctype; if (body && ctype_hdr && - !pj_stricmp2(&ctype_hdr->media.type, "multipart") && - (!pj_stricmp2(&ctype_hdr->media.subtype, "mixed") || - !pj_stricmp2(&ctype_hdr->media.subtype, "alternative"))) { + ast_sip_is_media_type_in(&ctype_hdr->media, &pjsip_media_type_multipart_mixed, + &pjsip_media_type_multipart_alternative, SENTINEL)) { pjsip_multipart_part *part = pjsip_multipart_get_first_part(body); while (part != NULL) { if (check_content_disposition_in_multipart(part)) { @@ -5488,7 +5487,7 @@ static void session_outgoing_nat_hook(pjsip_tx_data *tdata, struct ast_sip_trans /* SDP produced by us directly will never be multipart */ if (!transport_state || hook || !tdata->msg->body || - !ast_sip_is_content_type(&tdata->msg->body->content_type, "application", "sdp") || + !ast_sip_are_media_types_equal(&tdata->msg->body->content_type, &pjsip_media_type_application_sdp) || ast_strlen_zero(transport->external_media_address)) { return; }