comparison 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
comparison
equal deleted inserted replaced
-1:000000000000 0:35c0d9f03c0a
1 /*
2 * In this module we implement outgoing RTP stream generation.
3 */
4
5 #include <sys/types.h>
6 #include <sys/socket.h>
7 #include <sys/time.h>
8 #include <netinet/in.h>
9 #include <stdio.h>
10 #include <stdint.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <strings.h>
14 #include <unistd.h>
15 #include "../include/tmgw_const.h"
16 #include "../include/rtp_defs.h"
17 #include "../libutil/osmo_bits.h"
18
19 extern struct sockaddr_in rtp_local_addr, rtp_remote_addr;
20 extern int rtp_udp_fd, rtcp_udp_fd, pcma_selected;
21 extern struct timeval cur_event_time;
22
23 static uint32_t rtp_ssrc;
24 static uint32_t rtp_out_ts;
25 static uint16_t rtp_out_seq;
26
27 static uint8_t pcm_fill_octet;
28
29 static uint16_t tfo_fill_buf[9], tfo_req_buf[7];
30 static uint16_t *is_out_ptr;
31 static unsigned is_out_count;
32 static int tfo_stop_req;
33
34 void
35 assign_rtpout_ssrc()
36 {
37 rtp_ssrc = cur_event_time.tv_sec ^ cur_event_time.tv_usec ^ getpid();
38 }
39
40 void
41 init_pcm_fill_octet()
42 {
43 if (pcma_selected)
44 pcm_fill_octet = 0xD5;
45 else
46 pcm_fill_octet = 0xFF;
47 }
48
49 void
50 prepare_tfo_fill()
51 {
52 tfo_fill_buf[0] = 0x15A;
53 tfo_fill_buf[1] = 0x1A9;
54 tfo_fill_buf[2] = 0x129;
55 tfo_fill_buf[3] = 0x15A;
56 tfo_fill_buf[4] = 0x1A9;
57 tfo_fill_buf[5] = 0x129;
58 tfo_fill_buf[6] = 0x15A;
59 tfo_fill_buf[7] = 0x1A9;
60 tfo_fill_buf[8] = 0x129;
61 }
62
63 static void
64 insert_is_msg(payload, word)
65 uint8_t *payload;
66 uint16_t word;
67 {
68 ubit_t is_bits[10];
69 uint8_t *bytep;
70 unsigned n;
71
72 uint16_to_bits(word, is_bits, 10);
73 for (n = 0; n < 10; n++) {
74 bytep = payload + n * 16;
75 *bytep &= 0xFE;
76 *bytep |= is_bits[n];
77 }
78 }
79
80 void
81 generate_rtp_packet()
82 {
83 struct rtp_packet pkt;
84 socklen_t addrlen;
85
86 pkt.v_p_x_cc = 0x80;
87 pkt.m_pt = pcma_selected ? PSTN_CODEC_PCMA : PSTN_CODEC_PCMU;
88 pkt.seq = htons(rtp_out_seq++);
89 pkt.tstamp = htonl(rtp_out_ts);
90 rtp_out_ts += 160;
91 pkt.ssrc = rtp_ssrc;
92 memset(pkt.payload, pcm_fill_octet, RTP_MAX_PAYLOAD);
93 if (is_out_count) {
94 insert_is_msg(pkt.payload, *is_out_ptr++);
95 is_out_count--;
96 if (!is_out_count && !tfo_stop_req) {
97 is_out_ptr = tfo_req_buf;
98 is_out_count = 7;
99 }
100 }
101 addrlen = sizeof(struct sockaddr_in);
102 sendto(rtp_udp_fd, &pkt, RTP_PACKET_SIZE_PSTN, 0,
103 (struct sockaddr *) &rtp_remote_addr, addrlen);
104 }
105
106 void
107 set_pcm_fill_octet(oct)
108 unsigned oct;
109 {
110 pcm_fill_octet = oct;
111 }
112
113 void
114 send_tfo_req(sig, codec)
115 unsigned sig, codec;
116 {
117 tfo_req_buf[0] = 0x15A;
118 tfo_req_buf[1] = 0x1A9;
119 tfo_req_buf[2] = 0x05D;
120 tfo_req_buf[3] = 0x14E;
121 tfo_req_buf[4] = 0x14B;
122 encode_tfo_ext_words(sig, codec, 0, tfo_req_buf + 5);
123 is_out_ptr = tfo_fill_buf;
124 is_out_count = 9;
125 tfo_stop_req = 0;
126 }
127
128 void
129 stop_tfo_out()
130 {
131 tfo_stop_req = 1;
132 }