static int sangoma_create_rtp(void *usr_priv, sngtc_codec_request_leg_t *codec_reg_leg, sngtc_codec_reply_leg_t* codec_reply_leg, void **rtp_fd) { switch_rtp_t *rtp_session = NULL; switch_port_t rtp_port; char codec_ip[255]; char local_ip[255]; switch_rtp_flag_t flags = 0; int iana = 0; const char *err = NULL; struct sangoma_transcoding_session *sess = usr_priv; struct in_addr local_ip_addr = { 0 }; local_ip_addr.s_addr = htonl(codec_reply_leg->host_ip); switch_inet_ntop(AF_INET, &local_ip_addr, local_ip, sizeof(local_ip)); /* request a port */ if (!(rtp_port = switch_rtp_request_port(local_ip))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to allocate RTP port for IP %s\n", local_ip); return -1; } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Allocated port %d for IP %s\n", rtp_port, local_ip); codec_reg_leg->host_udp_port = rtp_port; sngtc_codec_ipv4_hex_to_str(codec_reply_leg->codec_ip, codec_ip); iana = codec_id_to_iana(codec_reg_leg->codec_id); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Creating RTP session for host (%s/%d) vocallo(%s/%d) Iana=%d ms=%d idx=%lu\n", local_ip, rtp_port, codec_ip, codec_reply_leg->codec_udp_port, iana, codec_reg_leg->ms*1000, sess->sessid); /* create the RTP socket, dont use the session pool since the session may go away while the RTP socket should linger around * until sangoma_transcode decides to kill it (possibly because the same RTP session is used for a different call) */ rtp_session = switch_rtp_new(local_ip, rtp_port, codec_ip, codec_reply_leg->codec_udp_port, iana, sess->impl->samples_per_packet, codec_reg_leg->ms*1000, /* microseconds per packet */ flags, NULL, &err, g_pool); if (!rtp_session) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to create switch rtp session: %s\n", err); return -1; } *rtp_fd = rtp_session; return 0; }
static int sangoma_create_rtp_port(void *usr_priv, uint32_t host_ip, uint32_t *p_rtp_port, void **rtp_fd) { struct in_addr local_ip_addr = { 0 }; char local_ip[255]; switch_port_t rtp_port; local_ip_addr.s_addr = htonl(host_ip); switch_inet_ntop(AF_INET, &local_ip_addr, local_ip, sizeof(local_ip)); /* request a port */ if (!(rtp_port = switch_rtp_request_port(local_ip))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to allocate RTP port for IP %s\n", local_ip); return -1; } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "New allocated port %d for IP %s/%d.%d.%d.%d\n", rtp_port, local_ip, SNGTC_NIPV4(host_ip)); *p_rtp_port = rtp_port; *rtp_fd = (void *)(long)rtp_port; return 0; }
static int oreka_setup_rtp(oreka_session_t *oreka, oreka_stream_type_t type) { switch_port_t rtp_port = 0; switch_rtp_flag_t flags[SWITCH_RTP_FLAG_INVALID] = {0}; switch_rtp_t *rtp_stream = NULL; switch_codec_implementation_t *codec_impl = NULL; switch_status_t status = SWITCH_STATUS_SUCCESS; int res = 0; const char *err = "unknown error"; const char *type_str = type == FS_OREKA_READ ? "read" : "write"; if (type == FS_OREKA_READ) { status = switch_core_session_get_read_impl(oreka->session, &oreka->read_impl); codec_impl = &oreka->read_impl; } else { status = switch_core_session_get_write_impl(oreka->session, &oreka->write_impl); codec_impl = &oreka->write_impl; } if (status != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No %s codec implementation available!\n", type_str); res = -1; goto done; } if (!(rtp_port = switch_rtp_request_port(globals.local_ipv4_str))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to allocate %s RTP port for IP %s\n", type_str, globals.local_ipv4_str); res = -1; goto done; } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Allocated %s port %d for local IP %s, destination IP %s\n", type_str, rtp_port, globals.local_ipv4_str, globals.sip_server_ipv4_str); rtp_stream = switch_rtp_new(globals.local_ipv4_str, rtp_port, globals.sip_server_ipv4_str, rtp_port, 0, /* PCMU IANA*/ codec_impl->samples_per_packet, codec_impl->microseconds_per_packet, flags, NULL, &err, switch_core_session_get_pool(oreka->session)); if (!rtp_stream) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to create %s RTP stream at %s:%d: %s\n", type_str, globals.local_ipv4_str, rtp_port, err); res = -1; goto done; } switch_rtp_intentional_bugs(rtp_stream, RTP_BUG_SEND_LINEAR_TIMESTAMPS); done: if (res == -1) { if (rtp_port) { switch_rtp_release_port(globals.local_ipv4_str, rtp_port); } if (rtp_stream) { switch_rtp_destroy(&rtp_stream); } } else { if (type == FS_OREKA_READ) { oreka->read_rtp_stream = rtp_stream; oreka->read_rtp_port = rtp_port; } else { oreka->write_rtp_stream = rtp_stream; oreka->write_rtp_port = rtp_port; } } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Successfully created %s RTP stream at %s:%d at %dms@%dHz\n", type_str, globals.local_ipv4_str, rtp_port, codec_impl->microseconds_per_packet/1000, codec_impl->samples_per_second); return res; }