osmo-ttcn3-hacks/mgw/RTP_Endpoint.ttcn

162 lines
4.5 KiB
Plaintext

module RTP_Endpoint {
import from General_Types all;
import from Osmocom_Types all;
import from IPL4asp_Types all;
import from RTP_Types all;
import from RTP_CodecPort all;
import from RTP_CodecPort_CtrlFunct all;
/* state for one of the two UDP sockets in and endpoint */
type record RtpEndpointSub {
ConnectionId connection_id,
HostName local_name,
PortNumber local_port,
HostName remote_name,
PortNumber remote_port
}
/* state for one RTP+RTCP endpoint */
type record RtpEndpoint {
/* static configuration */
INT7b payload_type,
integer sample_rate, /* e.g. 8000 */
integer samples_per_pkt, /* e.g. 160 */
BIT32_BO_LAST ssrc,
/* dynamic state */
uint32_t next_ts,
LIN2_BO_LAST next_seq_no,
RtpEndpointSub rtp,
RtpEndpointSub rtcp
}
/*
type component RTP_CT {
port RTP_CODEC_PT RTP;
ConnectionId g_conn_id := 1;
}
modulepar {
HostName rtp_local_ip := "127.0.0.1";
PortNumber rtp_local_base_port := 10000;
}
*/
template RTP_messages_union ts_RTP(BIT1 marker, INT7b pt, LIN2_BO_LAST seq, uint32_t ts,
BIT32_BO_LAST ssrc, octetstring data) := {
rtp := {
version := 2,
padding_ind := '0'B,
extension_ind := '0'B,
CSRC_count := 0,
marker_bit := marker,
payload_type := pt,
sequence_number := seq,
time_stamp := int2bit(ts, 32),
SSRC_id := ssrc,
CSRCs := omit,
ext_header := omit,
data := data
}
}
template RTP_messages_union tr_RTP(template INT7b pt, template octetstring data,
template BIT32_BO_LAST ssrc := ?,
template LIN2_BO_LAST seq := ?,
template BIT32_BO_LAST ts := ?) := {
rtp := {
version := 2,
padding_ind := ?,
extension_ind := ?,
CSRC_count := ?,
marker_bit := ?,
payload_type := pt,
sequence_number := seq,
time_stamp := ts,
SSRC_id := ssrc,
CSRCs := *,
ext_header := *,
data := data
}
}
function rtp_endpoint_init(inout RtpEndpoint ep, charstring local_name, PortNumber local_port,
uint32_t ssrc) {
ep.rtp.local_name := local_name;
ep.rtp.local_port := local_port;
ep.rtp.connection_id := -1;
ep.rtcp.local_name := local_name;
ep.rtcp.local_port := local_port + 1;
ep.rtcp.connection_id := -1;
ep.ssrc := int2bit(ssrc, 32);
ep.payload_type := 99;
ep.sample_rate := 8000;
ep.samples_per_pkt := 160;
ep.next_ts := float2int(rnd()*4294967295.0);
ep.next_seq_no := float2int(rnd()*65535.0);
}
function rtp_endpoint_sub_close(inout RTP_CODEC_PT RTP, inout RtpEndpointSub sub) {
if (sub.connection_id != -1) {
f_IPL4_close(RTP, sub.connection_id, { udp := {} });
sub.connection_id := -1;
}
}
function rtp_endpoint_sub_connect(inout RTP_CODEC_PT RTP, inout RtpEndpointSub sub) {
var Result res;
res := f_IPL4_connect(RTP, sub.remote_name, sub.remote_port,
sub.local_name, sub.local_port, sub.connection_id, { udp := {} });
if (not ispresent(res.connId)) {
setverdict(fail, "Could not connect RTP, check your configuration");
mtc.stop;
}
/* connect without previous bind: save conenction id allocated by IPL4asp */
if (sub.connection_id == -1) {
sub.connection_id := res.connId;
}
}
function rtp_endpoint_close(inout RTP_CODEC_PT RTP, inout RtpEndpoint ep) {
rtp_endpoint_sub_close(RTP, ep.rtp);
rtp_endpoint_sub_close(RTP, ep.rtcp);
}
/* connect the RTP and RTCP */
function rtp_endpoint_connect(inout RTP_CODEC_PT RTP, inout RtpEndpoint ep) {
rtp_endpoint_sub_connect(RTP, ep.rtp);
rtp_endpoint_sub_connect(RTP, ep.rtcp);
}
function rtp_endpoint_sub_bind(inout RTP_CODEC_PT RTP, inout RtpEndpointSub sub) {
var Result res;
rtp_endpoint_sub_close(RTP, sub);
res := f_IPL4_listen(RTP, sub.local_name, sub.local_port, { udp := {} });
if (not ispresent(res.connId)) {
setverdict(fail, "Could not listen to RTP, check your configuration");
mtc.stop;
}
sub.connection_id := res.connId;
}
function rtp_endpoint_bind(inout RTP_CODEC_PT RTP, inout RtpEndpoint ep) {
rtp_endpoint_sub_bind(RTP, ep.rtp);
rtp_endpoint_sub_bind(RTP, ep.rtcp);
}
/* send user-specified data through given endpoint, incrementing seq_no and timestamp */
function rtp_endpoint_send(inout RTP_CODEC_PT RTP, inout RtpEndpoint ep,
octetstring data := '00'O) {
var RTP_messages_union rtp;
/* generate RTP packet as abstract TTCN-3 type */
rtp := valueof(ts_RTP('0'B, ep.payload_type, ep.next_seq_no, ep.next_ts, ep.ssrc, data));
/* increment for next packet */
ep.next_seq_no := ep.next_seq_no + 1;
ep.next_ts := ep.next_ts + ep.samples_per_pkt;
/* encode and send */
RTP.send(t_RTP_Send(ep.rtp.connection_id, rtp));
}
}