/*! \brief Helper function which determines if the address within SDP should be rewritten */ static int multihomed_rewrite_sdp(struct pjmedia_sdp_session *sdp) { if (!sdp->conn) { return 0; } /* If the host address is used in the SDP replace it with the address of what this is going out on */ if ((!pj_strcmp2(&sdp->conn->addr_type, "IP4") && !pj_strcmp2(&sdp->conn->addr, ast_sip_get_host_ip_string(pj_AF_INET()))) || (!pj_strcmp2(&sdp->conn->addr_type, "IP6") && !pj_strcmp2(&sdp->conn->addr, ast_sip_get_host_ip_string(pj_AF_INET6())))) { return 1; } return 0; }
/*! \brief Function which creates an outgoing stream */ static int create_outgoing_sdp_stream(struct ast_sip_session *session, struct ast_sip_session_media *session_media, struct pjmedia_sdp_session *sdp) { pj_pool_t *pool = session->inv_session->pool_prov; static const pj_str_t STR_IN = { "IN", 2 }; static const pj_str_t STR_IP4 = { "IP4", 3}; static const pj_str_t STR_IP6 = { "IP6", 3}; static const pj_str_t STR_UDPTL = { "udptl", 5 }; static const pj_str_t STR_T38 = { "t38", 3 }; static const pj_str_t STR_TRANSFERREDTCF = { "transferredTCF", 14 }; static const pj_str_t STR_LOCALTCF = { "localTCF", 8 }; static const pj_str_t STR_T38UDPFEC = { "t38UDPFEC", 9 }; static const pj_str_t STR_T38UDPREDUNDANCY = { "t38UDPRedundancy", 16 }; struct t38_state *state; pjmedia_sdp_media *media; const char *hostip = NULL; struct ast_sockaddr addr; char tmp[512]; pj_str_t stmp; if (!session->endpoint->media.t38.enabled) { return 1; } else if ((session->t38state != T38_LOCAL_REINVITE) && (session->t38state != T38_PEER_REINVITE) && (session->t38state != T38_ENABLED)) { return 1; } else if (!(state = t38_state_get_or_alloc(session))) { return -1; } else if (t38_initialize_session(session, session_media)) { return -1; } if (!(media = pj_pool_zalloc(pool, sizeof(struct pjmedia_sdp_media))) || !(media->conn = pj_pool_zalloc(pool, sizeof(struct pjmedia_sdp_conn)))) { return -1; } media->desc.media = pj_str(session_media->stream_type); media->desc.transport = STR_UDPTL; if (ast_strlen_zero(session->endpoint->media.address)) { hostip = ast_sip_get_host_ip_string(session->endpoint->media.t38.ipv6 ? pj_AF_INET6() : pj_AF_INET()); } else { hostip = session->endpoint->media.address; } if (ast_strlen_zero(hostip)) { return -1; } media->conn->net_type = STR_IN; media->conn->addr_type = session->endpoint->media.t38.ipv6 ? STR_IP6 : STR_IP4; pj_strdup2(pool, &media->conn->addr, hostip); ast_udptl_get_us(session_media->udptl, &addr); media->desc.port = (pj_uint16_t) ast_sockaddr_port(&addr); media->desc.port_count = 1; media->desc.fmt[media->desc.fmt_count++] = STR_T38; snprintf(tmp, sizeof(tmp), "%u", state->our_parms.version); media->attr[media->attr_count++] = pjmedia_sdp_attr_create(pool, "T38FaxVersion", pj_cstr(&stmp, tmp)); snprintf(tmp, sizeof(tmp), "%u", t38_get_rate(state->our_parms.rate)); media->attr[media->attr_count++] = pjmedia_sdp_attr_create(pool, "T38MaxBitRate", pj_cstr(&stmp, tmp)); if (state->our_parms.fill_bit_removal) { media->attr[media->attr_count++] = pjmedia_sdp_attr_create(pool, "T38FaxFillBitRemoval", NULL); } if (state->our_parms.transcoding_mmr) { media->attr[media->attr_count++] = pjmedia_sdp_attr_create(pool, "T38FaxTranscodingMMR", NULL); } if (state->our_parms.transcoding_jbig) { media->attr[media->attr_count++] = pjmedia_sdp_attr_create(pool, "T38FaxTranscodingJBIG", NULL); } switch (state->our_parms.rate_management) { case AST_T38_RATE_MANAGEMENT_TRANSFERRED_TCF: media->attr[media->attr_count++] = pjmedia_sdp_attr_create(pool, "T38FaxRateManagement", &STR_TRANSFERREDTCF); break; case AST_T38_RATE_MANAGEMENT_LOCAL_TCF: media->attr[media->attr_count++] = pjmedia_sdp_attr_create(pool, "T38FaxRateManagement", &STR_LOCALTCF); break; } snprintf(tmp, sizeof(tmp), "%u", ast_udptl_get_local_max_datagram(session_media->udptl)); media->attr[media->attr_count++] = pjmedia_sdp_attr_create(pool, "T38FaxMaxDatagram", pj_cstr(&stmp, tmp)); switch (ast_udptl_get_error_correction_scheme(session_media->udptl)) { case UDPTL_ERROR_CORRECTION_NONE: break; case UDPTL_ERROR_CORRECTION_FEC: media->attr[media->attr_count++] = pjmedia_sdp_attr_create(pool, "T38FaxUdpEC", &STR_T38UDPFEC); break; case UDPTL_ERROR_CORRECTION_REDUNDANCY: media->attr[media->attr_count++] = pjmedia_sdp_attr_create(pool, "T38FaxUdpEC", &STR_T38UDPREDUNDANCY); break; } sdp->media[sdp->media_count++] = media; return 1; }