view sip-manual-out/rtp_tx.c @ 195:a3d71489672f

sip-manual-out: implement tfo-req command
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 17 Mar 2023 17:22:42 -0800
parents f8a33603288f
children d3c99b41fb04
line wrap: on
line source

/*
 * In this module we implement outgoing RTP stream generation.
 */

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include "../include/tmgw_const.h"
#include "../include/rtp_defs.h"
#include "../libutil/osmo_bits.h"

extern struct sockaddr_in rtp_local_addr, rtp_remote_addr;
extern int rtp_udp_fd, rtcp_udp_fd, pcma_selected;
extern struct timeval cur_event_time;

static uint32_t rtp_ssrc;
static uint32_t rtp_out_ts;
static uint16_t rtp_out_seq;

static uint16_t is_out_buf[7], *is_out_ptr;
static unsigned is_out_count;

void
assign_rtpout_ssrc()
{
	rtp_ssrc = cur_event_time.tv_sec ^ cur_event_time.tv_usec ^ getpid();
}

static void
insert_is_msg(payload, word)
	uint8_t *payload;
	uint16_t word;
{
	ubit_t is_bits[10];
	uint8_t *bytep;
	unsigned n;

	uint16_to_bits(word, is_bits, 10);
	for (n = 0; n < 10; n++) {
		bytep = payload + n * 16;
		*bytep &= 0xFE;
		*bytep |= is_bits[n];
	}
}

void
generate_rtp_packet()
{
	struct rtp_packet pkt;
	socklen_t addrlen;

	pkt.v_p_x_cc = 0x80;
	pkt.m_pt = pcma_selected ? PSTN_CODEC_PCMA : PSTN_CODEC_PCMU;
	pkt.seq = htons(rtp_out_seq++);
	pkt.tstamp = htonl(rtp_out_ts);
	rtp_out_ts += 160;
	pkt.ssrc = rtp_ssrc;
	memset(pkt.payload, pcma_selected ? 0xD5 : 0xFF, RTP_MAX_PAYLOAD);
	if (is_out_count) {
		insert_is_msg(pkt.payload, *is_out_ptr++);
		is_out_count--;
	}
	addrlen = sizeof(struct sockaddr_in);
	sendto(rtp_udp_fd, &pkt, RTP_PACKET_SIZE_PSTN, 0,
		(struct sockaddr *) &rtp_remote_addr, addrlen);
}

void
send_tfo_req(sig, codec)
	unsigned sig, codec;
{
	is_out_buf[0] = 0x15A;
	is_out_buf[1] = 0x1A9;
	is_out_buf[2] = 0x05D;
	is_out_buf[3] = 0x14E;
	is_out_buf[4] = 0x14B;
	encode_tfo_ext_words(sig, codec, 0, is_out_buf + 5);
	is_out_ptr = is_out_buf;
	is_out_count = 7;
}