FreeCalypso > hg > sipout-test-utils
diff test-voice/rtp_tx.c @ 0:35c0d9f03c0a
beginning with sipout-test-voice,
a copy of sip-manual-out from themwi-system-sw
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sun, 03 Mar 2024 23:20:19 -0800 |
parents | |
children | 059b79c9f0c3 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test-voice/rtp_tx.c Sun Mar 03 23:20:19 2024 -0800 @@ -0,0 +1,132 @@ +/* + * 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 uint8_t pcm_fill_octet; + +static uint16_t tfo_fill_buf[9], tfo_req_buf[7]; +static uint16_t *is_out_ptr; +static unsigned is_out_count; +static int tfo_stop_req; + +void +assign_rtpout_ssrc() +{ + rtp_ssrc = cur_event_time.tv_sec ^ cur_event_time.tv_usec ^ getpid(); +} + +void +init_pcm_fill_octet() +{ + if (pcma_selected) + pcm_fill_octet = 0xD5; + else + pcm_fill_octet = 0xFF; +} + +void +prepare_tfo_fill() +{ + tfo_fill_buf[0] = 0x15A; + tfo_fill_buf[1] = 0x1A9; + tfo_fill_buf[2] = 0x129; + tfo_fill_buf[3] = 0x15A; + tfo_fill_buf[4] = 0x1A9; + tfo_fill_buf[5] = 0x129; + tfo_fill_buf[6] = 0x15A; + tfo_fill_buf[7] = 0x1A9; + tfo_fill_buf[8] = 0x129; +} + +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, pcm_fill_octet, RTP_MAX_PAYLOAD); + if (is_out_count) { + insert_is_msg(pkt.payload, *is_out_ptr++); + is_out_count--; + if (!is_out_count && !tfo_stop_req) { + is_out_ptr = tfo_req_buf; + is_out_count = 7; + } + } + addrlen = sizeof(struct sockaddr_in); + sendto(rtp_udp_fd, &pkt, RTP_PACKET_SIZE_PSTN, 0, + (struct sockaddr *) &rtp_remote_addr, addrlen); +} + +void +set_pcm_fill_octet(oct) + unsigned oct; +{ + pcm_fill_octet = oct; +} + +void +send_tfo_req(sig, codec) + unsigned sig, codec; +{ + tfo_req_buf[0] = 0x15A; + tfo_req_buf[1] = 0x1A9; + tfo_req_buf[2] = 0x05D; + tfo_req_buf[3] = 0x14E; + tfo_req_buf[4] = 0x14B; + encode_tfo_ext_words(sig, codec, 0, tfo_req_buf + 5); + is_out_ptr = tfo_fill_buf; + is_out_count = 9; + tfo_stop_req = 0; +} + +void +stop_tfo_out() +{ + tfo_stop_req = 1; +}