Example #1
0
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;
}
Example #2
0
static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event,
													switch_caller_profile_t *outbound_profile,
													switch_core_session_t **new_session, 
													switch_memory_pool_t **pool,
													switch_originate_flag_t flags, switch_call_cause_t *cancel_cause)
{
    switch_channel_t *channel;
    char name[128];
    crtp_private_t *tech_pvt = NULL;    
    switch_caller_profile_t *caller_profile;
    switch_rtp_flag_t rtp_flags[SWITCH_RTP_FLAG_INVALID] = {0};
    
    const char *err;

    
    const char  *local_addr = switch_event_get_header_nil(var_event, kLOCALADDR),
                *szlocal_port = switch_event_get_header_nil(var_event, kLOCALPORT),
                *remote_addr = switch_event_get_header_nil(var_event, kREMOTEADDR),
                *szremote_port = switch_event_get_header_nil(var_event, kREMOTEPORT),
                *codec  = switch_event_get_header_nil(var_event, kCODEC),
                *szptime  = switch_event_get_header_nil(var_event, kPTIME),
                //*mode  = switch_event_get_header_nil(var_event, kMODE),
                //*szrfc2833_pt = switch_event_get_header_nil(var_event, kRFC2833PT),
                *szrate = switch_event_get_header_nil(var_event, kRATE),
                *szpt = switch_event_get_header_nil(var_event, kPT);
    
    
    switch_port_t local_port = !zstr(szlocal_port) ? atoi(szlocal_port) : 0,
                 remote_port = !zstr(szremote_port) ? atoi(szremote_port) : 0;
    
    int ptime  = !zstr(szptime) ? atoi(szptime) : 0,
        //rfc2833_pt = !zstr(szrfc2833_pt) ? atoi(szrfc2833_pt) : 0,
        rate = !zstr(szrate) ? atoi(szrate) : 8000,
        pt = !zstr(szpt) ? atoi(szpt) : 0;
    
        if (
            ((zstr(remote_addr) || remote_port == 0) && (zstr(local_addr) || local_port == 0)) ||
            zstr(codec) ||
            zstr(szpt)) {
        
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing required arguments\n");
        goto fail;
    }
    
    
    if (!(*new_session = switch_core_session_request(crtp.endpoint_interface, SWITCH_CALL_DIRECTION_OUTBOUND, 0, pool))) {
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't request session.\n");
        goto fail;
    }
    
    channel = switch_core_session_get_channel(*new_session);
    
    tech_pvt = switch_core_session_alloc(*new_session, sizeof *tech_pvt);
    tech_pvt->session = *new_session;
    tech_pvt->channel = channel;
    tech_pvt->local_address = switch_core_session_strdup(*new_session, local_addr);
    tech_pvt->local_port = local_port;
    tech_pvt->remote_address = switch_core_session_strdup(*new_session, remote_addr);
    tech_pvt->remote_port = remote_port;
    tech_pvt->ptime = ptime;
    tech_pvt->agreed_pt = pt;
    tech_pvt->dtmf_type = DTMF_2833; /* XXX */
    
    if (zstr(local_addr) || local_port == 0) {
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "The local address and port must be set\n");
        goto fail;
    } else if (zstr(remote_addr) || remote_port == 0) {
        tech_pvt->mode = RTP_RECVONLY;
    } else {
        tech_pvt->mode = RTP_SENDRECV;
    }
    
    switch_core_session_set_private(*new_session, tech_pvt);
    
    caller_profile = switch_caller_profile_clone(*new_session, outbound_profile);
    switch_channel_set_caller_profile(channel, caller_profile);
    
    
    snprintf(name, sizeof(name), "rtp/%s", outbound_profile->destination_number);
	switch_channel_set_name(channel, name);
    
    switch_channel_set_state(channel, CS_INIT);

	if (switch_core_codec_init(&tech_pvt->read_codec,
							   codec,
							   NULL,
							   rate,
							   ptime,
							   1,
							   /*SWITCH_CODEC_FLAG_ENCODE |*/ SWITCH_CODEC_FLAG_DECODE,
							   NULL, switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't load codec?\n");
        goto fail;
	} else {
		if (switch_core_codec_init(&tech_pvt->write_codec,
								   codec,
								   NULL,
								   rate,
								   ptime,
								   1,
								   SWITCH_CODEC_FLAG_ENCODE /*| SWITCH_CODEC_FLAG_DECODE*/, 
								   NULL, switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't load codec?\n");
            goto fail;
		}
	}
    
    if (switch_core_session_set_read_codec(*new_session, &tech_pvt->read_codec) != SWITCH_STATUS_SUCCESS) {
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't set read codec?\n");
        goto fail;
    }
    
    if (switch_core_session_set_write_codec(*new_session, &tech_pvt->write_codec) != SWITCH_STATUS_SUCCESS) {
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't set write codec?\n");
        goto fail;
    }
    
    if (!(tech_pvt->rtp_session = switch_rtp_new(local_addr, local_port, remote_addr, remote_port, tech_pvt->agreed_pt,
												 tech_pvt->read_codec.implementation->samples_per_packet, ptime * 1000,
												 rtp_flags, "soft", &err, switch_core_session_get_pool(*new_session)))) {
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't setup RTP session: [%s]\n", err);
        goto fail;
    }
    
    if (switch_core_session_thread_launch(*new_session) != SWITCH_STATUS_SUCCESS) {
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't start session thread.\n"); 
        goto fail;
    }
    
    switch_channel_mark_answered(channel);
    
    return SWITCH_CAUSE_SUCCESS;
    
fail:
     if (tech_pvt) {
        if (tech_pvt->read_codec.implementation) {
			switch_core_codec_destroy(&tech_pvt->read_codec);
		}
		
		if (tech_pvt->write_codec.implementation) {
			switch_core_codec_destroy(&tech_pvt->write_codec);
		}
    }
    
    if (*new_session) {
        switch_core_session_destroy(new_session);
    }
    return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
}
Example #3
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;
}