diff --git a/daemon/codec.c b/daemon/codec.c index fb69b2f30..9fdcb4198 100644 --- a/daemon/codec.c +++ b/daemon/codec.c @@ -1065,7 +1065,7 @@ static void __generator_stop(struct call_media *media) { } static void __t38_options_from_flags(struct t38_options *t_opts, const struct sdp_ng_flags *flags) { -#define t38_opt(name) t_opts->name = flags->t38_ ## name +#define t38_opt(name) t_opts->name = flags ? flags->t38_ ## name : 0 t38_opt(no_ecm); t38_opt(no_v17); t38_opt(no_v27ter); @@ -1083,7 +1083,7 @@ static void __check_t38_gateway(struct call_media *pcm_media, struct call_media t_opts = sp->t38_options; else { // create our own options - if (flags->t38_fec) + if (flags && flags->t38_fec) t_opts.fec_span = 3; t_opts.max_ec_entries = 3; } @@ -1938,10 +1938,11 @@ static int packet_dtmf_fwd(struct codec_ssrc_handler *ch, struct transcode_packe struct media_packet *mp) { int payload_type = -1; // take from handler's output config - struct codec_ssrc_handler *output_ch = NULL; - struct codec_ssrc_handler *decoder_ch = NULL; if (ch->handler->dtmf_scaler) { + struct codec_ssrc_handler *output_ch = NULL; + struct codec_ssrc_handler *decoder_ch = NULL; + // this is actually a DTMF -> PCM handler // grab our underlying PCM transcoder struct codec_handler *decoder_handler = __decoder_handler(ch->handler, mp); @@ -1964,14 +1965,14 @@ static int packet_dtmf_fwd(struct codec_ssrc_handler *ch, struct transcode_packe if (ch->dtmf_ts != packet->ts) { // this is a new event ch->dtmf_ts = packet->ts; // start TS - ch->last_dtmf_event_ts = 0; // last shifted FIFO PTS + ch->last_dtmf_event_ts = 0; // last DTMF event duration } - unsigned long ts = output_ch->encoder->fifo_pts; + unsigned long ts = output_ch->encoder->next_pts / output_ch->encoder->def->clockrate_mult; // roll back TS to start of event ts -= ch->last_dtmf_event_ts; // adjust to output RTP TS - unsigned long packet_ts = ts / output_ch->encoder->def->clockrate_mult + output_ch->first_ts; + unsigned long packet_ts = ts + output_ch->first_ts; ilogs(transcoding, LOG_DEBUG, "Scaling DTMF packet timestamp and duration: TS %lu -> %lu " "(%u -> %u)", @@ -1986,18 +1987,18 @@ static int packet_dtmf_fwd(struct codec_ssrc_handler *ch, struct transcode_packe dtmf->duration = htons(duration); // shift forward our output RTP TS - output_ch->encoder->fifo_pts = ts + duration; + output_ch->encoder->next_pts = (ts + duration) * output_ch->encoder->def->clockrate_mult; output_ch->encoder->packet_pts += (duration - ch->last_dtmf_event_ts) * output_ch->encoder->def->clockrate_mult; ch->last_dtmf_event_ts = duration; } payload_type = ch->handler->dtmf_payload_type; - } skip: - if (output_ch) - obj_put(&output_ch->h); - if (decoder_ch) - obj_put(&decoder_ch->h); + if (output_ch) + obj_put(&output_ch->h); + if (decoder_ch) + obj_put(&decoder_ch->h); + } char *buf = malloc(packet->payload->len + sizeof(struct rtp_header) + RTP_BUFFER_TAIL_ROOM); memcpy(buf + sizeof(struct rtp_header), packet->payload->s, packet->payload->len); diff --git a/daemon/jitter_buffer.c b/daemon/jitter_buffer.c index ac25a4f16..26593ecb6 100644 --- a/daemon/jitter_buffer.c +++ b/daemon/jitter_buffer.c @@ -99,6 +99,9 @@ static int get_clock_rate(struct media_packet *mp, int payload_type) { } static struct jb_packet* get_jb_packet(struct media_packet *mp, const str *s) { + if (rtp_payload(&mp->rtp, &mp->payload, &mp->raw)) + return NULL; + char *buf = malloc(s->len + RTP_BUFFER_HEAD_ROOM + RTP_BUFFER_TAIL_ROOM); if (!buf) { ilog(LOG_ERROR, "Failed to allocate memory: %s", strerror(errno)); @@ -113,11 +116,6 @@ static struct jb_packet* get_jb_packet(struct media_packet *mp, const str *s) { str_init_len(&p->mp.raw, buf + RTP_BUFFER_HEAD_ROOM, s->len); memcpy(p->mp.raw.s, s->s, s->len); - if(rtp_payload(&p->mp.rtp, &p->mp.payload, &p->mp.raw)) { - jb_packet_free(&p); - return NULL; - } - return p; } diff --git a/daemon/media_socket.c b/daemon/media_socket.c index 9ea26974a..8c32a0215 100644 --- a/daemon/media_socket.c +++ b/daemon/media_socket.c @@ -1939,9 +1939,12 @@ void media_packet_copy(struct media_packet *dst, const struct media_packet *src) dst->raw = STR_NULL; } void media_packet_release(struct media_packet *mp) { - obj_put(mp->sfd); - obj_put(&mp->ssrc_in->parent->h); - obj_put(&mp->ssrc_out->parent->h); + if (mp->sfd) + obj_put(mp->sfd); + if (mp->ssrc_in) + obj_put(&mp->ssrc_in->parent->h); + if (mp->ssrc_out) + obj_put(&mp->ssrc_out->parent->h); g_queue_clear_full(&mp->packets_out, codec_packet_free); g_free(mp->rtp); g_free(mp->rtcp); diff --git a/daemon/udp_listener.c b/daemon/udp_listener.c index 66f3e6572..6ce3ae377 100644 --- a/daemon/udp_listener.c +++ b/daemon/udp_listener.c @@ -44,7 +44,7 @@ static void udp_listener_incoming(int fd, void *p, uintptr_t x) { continue; if (errno != EWOULDBLOCK && errno != EAGAIN) ilog(LOG_WARNING, "Error reading from UDP socket"); - return; + break; } udp_buf->str.s[len] = '\0'; @@ -61,6 +61,8 @@ static void udp_listener_incoming(int fd, void *p, uintptr_t x) { udp_buf = NULL; } } + if (udp_buf) + obj_put(udp_buf); } static void __ulc_free(void *p) { diff --git a/lib/codeclib.c b/lib/codeclib.c index 79e1e5dbc..e5c684f40 100644 --- a/lib/codeclib.c +++ b/lib/codeclib.c @@ -1285,11 +1285,17 @@ int encoder_input_data(encoder_t *enc, AVFrame *frame, return -1; if (enc->avpkt.size) { + // don't rely on the encoder producing steady timestamps, + // instead keep track of them ourselves based on the returned + // frame duration + enc->avpkt.pts = enc->next_pts; + if (enc->def->codec_type->encoder_got_packet) enc->def->codec_type->encoder_got_packet(enc); callback(enc, u1, u2); + enc->next_pts += enc->avpkt.duration; enc->mux_dts = enc->avpkt.dts + 1; // min next expected dts av_packet_unref(&enc->avpkt); diff --git a/lib/codeclib.h b/lib/codeclib.h index 7af12fdce..cda735ce9 100644 --- a/lib/codeclib.h +++ b/lib/codeclib.h @@ -240,6 +240,7 @@ struct encoder_s { AVAudioFifo *fifo; int64_t fifo_pts; // pts of first data in fifo int64_t packet_pts; // first pts of data in packetizer buffer + int64_t next_pts; // next pts expected from the encoder int ptime; int bitrate; int samples_per_frame; // for encoding diff --git a/t/auto-daemon-tests-dtx.pl b/t/auto-daemon-tests-dtx.pl index 2d8c992e5..68e103d7b 100755 --- a/t/auto-daemon-tests-dtx.pl +++ b/t/auto-daemon-tests-dtx.pl @@ -303,11 +303,67 @@ Time::HiRes::usleep(10000); # 10 ms snd($sock_a, $port_b, rtp(111, 9, 2560, 0x5678, "\xf0\x44\x0c\x00\x0a\x07\x41\x71\xa0\xf8\xc1\x54\x3c\x00\x00\x00\x00\x20")); rcv($sock_b, $port_a, rtpm(9, 9, 1600, $ssrc, "\xfb\xb8\xde\xde\x71\xb6\xfb\xdf\xf6\xf8\x9a\xfb\xf4\xf4\x78\xf6\x9f\x5f\xb8\xbb\xfb\x78\xf8\xfa\xfa\xb8\xfa\xfa\xf8\x7a\x5e\xb4\xb8\xfa\xb7\x5e\xec\x78\xf8\xba\xde\x78\xba\xde\x78\x73\xde\xb8\xf5\xb5\x7a\xde\xf1\x70\xf6\xdf\xdf\x9f\xfb\xb8\x74\xf6\x76\xdf\xdc\xb8\xdc\x9f\x70\x74\x76\xdf\xdf\x9f\xb8\xfb\x78\x74\xf6\xfb\xdc\xb2\xdc\xdc\x5f\xf4\xf2\xfb\xdd\xb9\xf8\xfb\x9f\xdc\x7b\xb6\xfb\xf8\xf8\x9e\xfa\x78\xdc\xf5\xb8\x75\xb5\xfa\x5c\xf5\xf5\x9f\xf8\xf5\xf5\x76\x9c\x70\x96\xdf\xf9\x76\xf6\xb9\x73\x9b\x7b\xdf\xfb\xf4\xf4\xf7\x9d\xdd\x59\xf7\x77\xb5\xf9\xf9\xb9\xfb\xd9\x77\xf5\xf9\xf7\xb9\xf7\xdd\xdf\xf7\xb9\xf7\x9d\x5f\xf7\xf9\xf9\xf7")); +# reverse flow +snd($sock_b, $port_a, rtp(9, 100, 7000, 0x9876, "\xfb\xb8\xde\xde\x71\xb6\xfb\xdf\xf6\xf8\x9a\xfb\xf4\xf4\x78\xf6\x9f\x5f\xb8\xbb\xfb\x78\xf8\xfa\xfa\xb8\xfa\xfa\xf8\x7a\x5e\xb4\xb8\xfa\xb7\x5e\xec\x78\xf8\xba\xde\x78\xba\xde\x78\x73\xde\xb8\xf5\xb5\x7a\xde\xf1\x70\xf6\xdf\xdf\x9f\xfb\xb8\x74\xf6\x76\xdf\xdc\xb8\xdc\x9f\x70\x74\x76\xdf\xdf\x9f\xb8\xfb\x78\x74\xf6\xfb\xdc\xb2\xdc\xdc\x5f\xf4\xf2\xfb\xdd\xb9\xf8\xfb\x9f\xdc\x7b\xb6\xfb\xf8\xf8\x9e\xfa\x78\xdc\xf5\xb8\x75\xb5\xfa\x5c\xf5\xf5\x9f\xf8\xf5\xf5\x76\x9c\x70\x96\xdf\xf9\x76\xf6\xb9\x73\x9b\x7b\xdf\xfb\xf4\xf4\xf7\x9d\xdd\x59\xf7\x77\xb5\xf9\xf9\xb9\xfb\xd9\x77\xf5\xf9\xf7\xb9\xf7\xdd\xdf\xf7\xb9\xf7\x9d\x5f\xf7\xf9\xf9\xf7")); +Time::HiRes::usleep(9000); +($ssrc) = rcv($sock_a, $port_b, rtpm(111, 100, 7000, -1, "\xf1\x54\x54\x3c\x58\x28\x92\xb6\x34\x42\x0b\x59\x8b\x52\x1c\x0d\xa0\xa6\x70\x16\xf8\x9a\x2d\x5e\xf0\x53\xb6\x78\x02\x1d\xff\x54\x12")); +Time::HiRes::usleep(9000); +snd($sock_b, $port_a, rtp(9, 101, 7160, 0x9876, "\xfb\xb8\xde\xde\x71\xb6\xfb\xdf\xf6\xf8\x9a\xfb\xf4\xf4\x78\xf6\x9f\x5f\xb8\xbb\xfb\x78\xf8\xfa\xfa\xb8\xfa\xfa\xf8\x7a\x5e\xb4\xb8\xfa\xb7\x5e\xec\x78\xf8\xba\xde\x78\xba\xde\x78\x73\xde\xb8\xf5\xb5\x7a\xde\xf1\x70\xf6\xdf\xdf\x9f\xfb\xb8\x74\xf6\x76\xdf\xdc\xb8\xdc\x9f\x70\x74\x76\xdf\xdf\x9f\xb8\xfb\x78\x74\xf6\xfb\xdc\xb2\xdc\xdc\x5f\xf4\xf2\xfb\xdd\xb9\xf8\xfb\x9f\xdc\x7b\xb6\xfb\xf8\xf8\x9e\xfa\x78\xdc\xf5\xb8\x75\xb5\xfa\x5c\xf5\xf5\x9f\xf8\xf5\xf5\x76\x9c\x70\x96\xdf\xf9\x76\xf6\xb9\x73\x9b\x7b\xdf\xfb\xf4\xf4\xf7\x9d\xdd\x59\xf7\x77\xb5\xf9\xf9\xb9\xfb\xd9\x77\xf5\xf9\xf7\xb9\xf7\xdd\xdf\xf7\xb9\xf7\x9d\x5f\xf7\xf9\xf9\xf7")); +Time::HiRes::usleep(9000); +rcv($sock_a, $port_b, rtpm(111, 101, 7320, $ssrc, "\xf1\x58\x42\x86\x17\xb7\xe1\xa2\x9c\x79\x5b\x43\x82\x64\xcc\xd1\xe0\xe4\xf8\x67\x69\x3d\x3e\x9e\xd8\x75\x34\xa9\xb2\xa5\x47\x81\x32")); +Time::HiRes::usleep(9000); +snd($sock_b, $port_a, rtp(9, 102, 7320, 0x9876, "\xfb\xb8\xde\xde\x71\xb6\xfb\xdf\xf6\xf8\x9a\xfb\xf4\xf4\x78\xf6\x9f\x5f\xb8\xbb\xfb\x78\xf8\xfa\xfa\xb8\xfa\xfa\xf8\x7a\x5e\xb4\xb8\xfa\xb7\x5e\xec\x78\xf8\xba\xde\x78\xba\xde\x78\x73\xde\xb8\xf5\xb5\x7a\xde\xf1\x70\xf6\xdf\xdf\x9f\xfb\xb8\x74\xf6\x76\xdf\xdc\xb8\xdc\x9f\x70\x74\x76\xdf\xdf\x9f\xb8\xfb\x78\x74\xf6\xfb\xdc\xb2\xdc\xdc\x5f\xf4\xf2\xfb\xdd\xb9\xf8\xfb\x9f\xdc\x7b\xb6\xfb\xf8\xf8\x9e\xfa\x78\xdc\xf5\xb8\x75\xb5\xfa\x5c\xf5\xf5\x9f\xf8\xf5\xf5\x76\x9c\x70\x96\xdf\xf9\x76\xf6\xb9\x73\x9b\x7b\xdf\xfb\xf4\xf4\xf7\x9d\xdd\x59\xf7\x77\xb5\xf9\xf9\xb9\xfb\xd9\x77\xf5\xf9\xf7\xb9\xf7\xdd\xdf\xf7\xb9\xf7\x9d\x5f\xf7\xf9\xf9\xf7")); +Time::HiRes::usleep(9000); +rcv($sock_a, $port_b, rtpm(111, 102, 7640, $ssrc, "\xf1\x50\x42\xfe\x51\x93\xf0\x66\xe8\x59\xeb\xb8\x05\x4a\x5a\x01\xa2\x3d\xf0\x29\x4d\xbd\x9c\x2e\x9f\x2d\x3f\x85\xfa\x1d\x47\x1f\xfa")); +# DTMF +Time::HiRes::usleep(9000); +snd($sock_b, $port_a, rtp(96, 103, 7480, 0x9876, "\x01\x07\x00\xa0")); +Time::HiRes::usleep(9000); +rcv($sock_a, $port_b, rtpm(101, 103, 7960, $ssrc, "\x01\x07\x01\x40")); +Time::HiRes::usleep(9000); +snd($sock_b, $port_a, rtp(96, 104, 7480, 0x9876, "\x01\x07\x01\x40")); +Time::HiRes::usleep(9000); +rcv($sock_a, $port_b, rtpm(101, 104, 7960, $ssrc, "\x01\x07\x02\x80")); +# end +Time::HiRes::usleep(9000); +snd($sock_b, $port_a, rtp(96, 105, 7480, 0x9876, "\x01\x87\x01\xe0")); +Time::HiRes::usleep(1000); +snd($sock_b, $port_a, rtp(96, 106, 7480, 0x9876, "\x01\x87\x01\xe0")); +Time::HiRes::usleep(1000); +snd($sock_b, $port_a, rtp(96, 107, 7480, 0x9876, "\x01\x87\x01\xe0")); +Time::HiRes::usleep(9000); +rcv($sock_a, $port_b, rtpm(101, 105, 7960, $ssrc, "\x01\x87\x03\xc0")); +Time::HiRes::usleep(1000); +rcv($sock_a, $port_b, rtpm(101, 106, 7960, $ssrc, "\x01\x87\x03\xc0")); +Time::HiRes::usleep(1000); +rcv($sock_a, $port_b, rtpm(101, 107, 7960, $ssrc, "\x01\x87\x03\xc0")); +Time::HiRes::usleep(9000); +# more audio +snd($sock_b, $port_a, rtp(9, 108, 7960, 0x9876, "\xfb\xb8\xde\xde\x71\xb6\xfb\xdf\xf6\xf8\x9a\xfb\xf4\xf4\x78\xf6\x9f\x5f\xb8\xbb\xfb\x78\xf8\xfa\xfa\xb8\xfa\xfa\xf8\x7a\x5e\xb4\xb8\xfa\xb7\x5e\xec\x78\xf8\xba\xde\x78\xba\xde\x78\x73\xde\xb8\xf5\xb5\x7a\xde\xf1\x70\xf6\xdf\xdf\x9f\xfb\xb8\x74\xf6\x76\xdf\xdc\xb8\xdc\x9f\x70\x74\x76\xdf\xdf\x9f\xb8\xfb\x78\x74\xf6\xfb\xdc\xb2\xdc\xdc\x5f\xf4\xf2\xfb\xdd\xb9\xf8\xfb\x9f\xdc\x7b\xb6\xfb\xf8\xf8\x9e\xfa\x78\xdc\xf5\xb8\x75\xb5\xfa\x5c\xf5\xf5\x9f\xf8\xf5\xf5\x76\x9c\x70\x96\xdf\xf9\x76\xf6\xb9\x73\x9b\x7b\xdf\xfb\xf4\xf4\xf7\x9d\xdd\x59\xf7\x77\xb5\xf9\xf9\xb9\xfb\xd9\x77\xf5\xf9\xf7\xb9\xf7\xdd\xdf\xf7\xb9\xf7\x9d\x5f\xf7\xf9\xf9\xf7")); +Time::HiRes::usleep(9000); +rcv($sock_a, $port_b, rtpm(111, 108, 8920, $ssrc, "\xf1\x50\x42\x86\xbe\xb7\x49\xe3\x7c\x53\x43\x18\x47\xe1\x6c\x71\xa2\xf6\x76\x20\xcd\x3f\x1f\x7a\x9e\x17\x06\xdc\x72\xf4\xf4\x5f\x7a")); +Time::HiRes::usleep(9000); +snd($sock_b, $port_a, rtp(9, 109, 8120, 0x9876, "\xfb\xb8\xde\xde\x71\xb6\xfb\xdf\xf6\xf8\x9a\xfb\xf4\xf4\x78\xf6\x9f\x5f\xb8\xbb\xfb\x78\xf8\xfa\xfa\xb8\xfa\xfa\xf8\x7a\x5e\xb4\xb8\xfa\xb7\x5e\xec\x78\xf8\xba\xde\x78\xba\xde\x78\x73\xde\xb8\xf5\xb5\x7a\xde\xf1\x70\xf6\xdf\xdf\x9f\xfb\xb8\x74\xf6\x76\xdf\xdc\xb8\xdc\x9f\x70\x74\x76\xdf\xdf\x9f\xb8\xfb\x78\x74\xf6\xfb\xdc\xb2\xdc\xdc\x5f\xf4\xf2\xfb\xdd\xb9\xf8\xfb\x9f\xdc\x7b\xb6\xfb\xf8\xf8\x9e\xfa\x78\xdc\xf5\xb8\x75\xb5\xfa\x5c\xf5\xf5\x9f\xf8\xf5\xf5\x76\x9c\x70\x96\xdf\xf9\x76\xf6\xb9\x73\x9b\x7b\xdf\xfb\xf4\xf4\xf7\x9d\xdd\x59\xf7\x77\xb5\xf9\xf9\xb9\xfb\xd9\x77\xf5\xf9\xf7\xb9\xf7\xdd\xdf\xf7\xb9\xf7\x9d\x5f\xf7\xf9\xf9\xf7")); +Time::HiRes::usleep(9000); +rcv($sock_a, $port_b, rtpm(111, 109, 9240, $ssrc, "\xf1\x58\x43\x82\x36\x15\x27\x26\xb5\x6a\xfb\x25\xc1\x21\x4c\x69\xe5\x76\x06\x4a\xe0\x6e\x9a\xbe\x9c\x87\x52\x8c\xf7\x67\xe5\xa7\xf6")); +# more DTMF +Time::HiRes::usleep(9000); +snd($sock_b, $port_a, rtp(96, 110, 8280, 0x9876, "\x01\x07\x00\xa0")); +Time::HiRes::usleep(9000); +rcv($sock_a, $port_b, rtpm(101, 110, 9560, $ssrc, "\x01\x07\x01\x40")); +Time::HiRes::usleep(9000); +snd($sock_b, $port_a, rtp(96, 111, 8280, 0x9876, "\x01\x07\x01\x40")); +Time::HiRes::usleep(9000); +rcv($sock_a, $port_b, rtpm(101, 111, 9560, $ssrc, "\x01\x07\x02\x80")); + + + rtpe_req('delete', 'AMR w DTMF', { 'from-tag' => ft() }); + ($sock_a, $sock_b) = new_call([qw(198.51.100.10 4042)], [qw(198.51.100.10 4044)]); ($port_a) = offer('AMR w reverse DTMF', @@ -426,6 +482,115 @@ Time::HiRes::usleep(9000); snd($sock_b, $port_a, rtp(97, 2, 1280, 0x6543, "\x01\x07\x01\x40")); Time::HiRes::usleep(9000); rcv($sock_a, $port_b, rtpm(101, 2, 1120, $ssrc, "\x01\x07\x00\xa0")); +Time::HiRes::usleep(9000); +snd($sock_b, $port_a, rtp(97, 3, 1280, 0x6543, "\x01\x07\x02\x80")); +Time::HiRes::usleep(9000); +rcv($sock_a, $port_b, rtpm(101, 3, 1120, $ssrc, "\x01\x07\x01\x40")); +Time::HiRes::usleep(9000); +snd($sock_b, $port_a, rtp(97, 4, 1280, 0x6543, "\x01\x07\x03\xc0")); +Time::HiRes::usleep(9000); +rcv($sock_a, $port_b, rtpm(101, 4, 1120, $ssrc, "\x01\x07\x01\xe0")); +Time::HiRes::usleep(9000); +snd($sock_b, $port_a, rtp(97, 5, 1280, 0x6543, "\x01\x07\x05\x00")); +Time::HiRes::usleep(9000); +rcv($sock_a, $port_b, rtpm(101, 5, 1120, $ssrc, "\x01\x07\x02\x80")); +Time::HiRes::usleep(9000); +# end +snd($sock_b, $port_a, rtp(97, 6, 1280, 0x6543, "\x01\x87\x06\x40")); +Time::HiRes::usleep(9000); +rcv($sock_a, $port_b, rtpm(101, 6, 1120, $ssrc, "\x01\x87\x03\x20")); +Time::HiRes::usleep(9000); +snd($sock_b, $port_a, rtp(97, 7, 1280, 0x6543, "\x01\x87\x06\x40")); +Time::HiRes::usleep(9000); +rcv($sock_a, $port_b, rtpm(101, 7, 1120, $ssrc, "\x01\x87\x03\x20")); +Time::HiRes::usleep(9000); +snd($sock_b, $port_a, rtp(97, 8, 1280, 0x6543, "\x01\x87\x06\x40")); +Time::HiRes::usleep(9000); +rcv($sock_a, $port_b, rtpm(101, 8, 1120, $ssrc, "\x01\x87\x03\x20")); +Time::HiRes::usleep(9000); +# some audio +snd($sock_b, $port_a, rtp(96, 9, 2880, 0x6543, "\xf1\x70\xcc\x2c\xb0\xbe\x3c\x2b\x21\x51\x80\x0c\x35\xf1\xf0\xef\xf5\x4c\x56\xe1\xad\x13\x8f\x83\x6a\xad\x1f\x1a\xec\x90\x25\x17\x36")); +Time::HiRes::usleep(9000); +rcv($sock_a, $port_b, rtpm(9, 9, 1920, $ssrc, "\xb8\xf8\xfa\x9e\xf4\xfa\xf7\xfa\xf7\xf8\xde\xf7\xb8\x7a\xba\xf7\x9b\xec\xfb\xb8\xfa\x78\xf8\xdc\x75\x9e\xb3\xf8\xde\xf8\xf5\xfa\x5e\xf3\xb8\xdf\xb8\xf5\xde\x78\xf5\xf5\xf8\xb3\xdf\xb6\xdf\xdf\xfb\x78\xbb\xfa\xba\xf8\xf8\x7a\xde\xfa\xba\xb5\x75\xf8\xf5\xdc\xfa\xf8\xb8\x78\xba\xfa\xfa\x5e\xf4\xba\x77\xfa\xfa\xba\xf7\xdb\x74\xb7\xf8\x78\xde\xb4\xf5\xf3\x5e\xba\x59\xf3\xfb\xdc\xb8\xf5\x71\xdc\xf8\xfb\xb8\xdf\xf5\xf8\xb5\x76\x9c\xdf\xf4\xdc\x3b\xb8\xf8\xd9\xfa\xf8\xf3\x5f\x7b\xb8\xfa\xfa\xdc\xb5\x78\xf5\xfa\xfa\x78\xba\xde\xfa\xb8\xf8\x77\xf8\xb8\x5e\x7a\xb7\xfa\xf7\x7a\x74\xba\xde\xf4\xdb\xb3\x73\xfb\x74\x9c\xf8\x5f\xb8\xfa\xf8\x78\xfa")); +Time::HiRes::usleep(9000); +snd($sock_b, $port_a, rtp(96, 10, 3200, 0x6543, "\xf1\x70\xcc\x2c\xb0\xbe\x3c\x2b\x21\x51\x80\x0c\x35\xf1\xf0\xef\xf5\x4c\x56\xe1\xad\x13\x8f\x83\x6a\xad\x1f\x1a\xec\x90\x25\x17\x36")); +Time::HiRes::usleep(9000); +rcv($sock_a, $port_b, rtpm(9, 10, 2080, $ssrc, "\x9c\x7a\xb5\xf5\xf5\x7a\xf5\xf8\x78\x9c\xba\xf5\x78\xf8\xfa\x7a\xba\xf4\x7a\x9b\xf1\xf3\x7b\xda\xf8\xfb\xbb\x78\xba\xf3\x5f\x9c\x78\xf5\xf4\xf8\xf6\xdc\x9c\xdc\x78\xf5\xf5\xb0\xf8\xfb\xdc\x5a\xb6\x7b\xb8\xf4\xb4\xfb\x5a\xf6\x5d\xf8\xb6\xb8\x74\x5a\xb4\xd8\x79\x74\xb9\xf4\xdd\xf9\x79\xdf\xf6\xfb\xf6\x5f\xfb\xbb\x9f\x7b\xf6\xfb\xfb\xdf\x5f\xb8\xfb\xf3\xb8\x7b\xdc\xf8\x78\x9e\xf5\xb5\x74\x9f\xf8\x7b\xfa\x7a\xde\xb3\xdc\xfa\x75\xb6\x7b\xda\xf6\xfb\xdf\x7b\x9f\xf3\xfb\xf8\x5c\xb6\xf6\xdf\xdf\xb8\xf6\xfb\xfb\xfb\x7a\x9c\xfa\xfa\xb8\xf5\x75\xb3\xfb\xdc\x1f\xb3\xfb\xdf\xf6\x7b\xbb\xdc\x75\xfb\xfb\x7a\xb8\xf8\x9e\xf5\x7a\xf5\x7a\xfa\xf8\x9c")); +Time::HiRes::usleep(9000); +snd($sock_b, $port_a, rtp(96, 11, 3520, 0x6543, "\xf1\x70\xcc\x2c\xb0\xbe\x3c\x2b\x21\x51\x80\x0c\x35\xf1\xf0\xef\xf5\x4c\x56\xe1\xad\x13\x8f\x83\x6a\xad\x1f\x1a\xec\x90\x25\x17\x36")); +Time::HiRes::usleep(9000); +rcv($sock_a, $port_b, rtpm(9, 11, 2240, $ssrc, "\xdc\xfa\xf5\x78\xf8\xba\xfa\xba\x77\x9b\xf3\xf8\xf3\x78\xfa\x9e\xfa\xf5\x5e\xb5\xf5\x71\xbb\xfb\x7b\xd6\xb2\x5f\xfb\xb9\x76\xdf\xdf\x74\xbb\xdf\xf8\x78\x9f\xf8\x76\xbb\x5f\xb8\xf8\x78\x7a\xde\xf1\x78\x9e\xf8\xfa\xb5\xde\x75\x75\xfa\xf5\xf8\x75\x9f\xb3\xda\xf4\x36\xdd\x79\x9f\xf4\xf8\xfb\xf8\x7b\x78\xfb\xbb\xde\xb5\xf8\x7a\x75\xf8\xf8\xde\xb5\xf8\xf3\xfb\x5c\x5e\xf5\xb6\xdf\xb2\xfb\xf8\xdc\xdc\x7b\xf8\xf5\xb6\x9f\xf6\xdc\x78\xf8\xb8\xf5\xfa\xf8\x9e\x5e\xfa\xb5\xf5\xf8\x3a\xba\xfa\xde\x7a\xba\x74\x78\xfa\xba\xfa\xde\xf2\x5c\xf5\x78\xf8\xb8\xba\xde\x34\xf7\xf8\xfa\xba\x5e\xb2\xde\x73\x5e\xf5\xf5\xf8\xf3\xbb\x7b\x5c\xb8\xfa\x5e\xf5\xf5")); +Time::HiRes::usleep(9000); +snd($sock_b, $port_a, rtp(96, 12, 3840, 0x6543, "\xf1\x70\xcc\x2c\xb0\xbe\x3c\x2b\x21\x51\x80\x0c\x35\xf1\xf0\xef\xf5\x4c\x56\xe1\xad\x13\x8f\x83\x6a\xad\x1f\x1a\xec\x90\x25\x17\x36")); +Time::HiRes::usleep(9000); +rcv($sock_a, $port_b, rtpm(9, 12, 2400, $ssrc, "\xf8\xf8\xf8\xf5\x7a\xdc\xb5\xb5\x71\xfb\x9f\x78\xf2\x7b\x9a\xf6\xbb\x7b\x5c\xf8\xf4\x78\xb6\xdc\xf8\xdc\xf8\x78\x9e\xf1\x76\xbb\xdc\xf8\xf8\x7a\xde\xf8\xba\xf5\x75\xb8\x78\x9e\xfa\x78\xf8\xba\xf8\x73\xdc\xb5\x7a\xde\xf5\xf8\xf3\xfa\xde\xb5\x78\xdc\xb3\xfb\x7b\xf8\x9e\xde\xfa\xf8\x35\xf3\xf8\xfa\x9c\xba\xfa\x5e\xf3\x78\x5e\xb8\xb8\xf5\x5e\xf8\x75\x75\xb8\xfa\xba\x7a\xde\x78\xb5\xf5\xf1\x7b\xde\xf8\xf8\xba\xfa\xf8\xde\x78\xf8\xb7\xf5\xf5\x5e\x9e\xb8\x5c\x75\xf3\xf3\xdc\xda\xb6\xfb\x78\xdc\xb4\xf6\x5f\xf8\x9f\xf6\xdf\x76\x7b\x9f\xf8\x9e\xf1\xf8\xdf\x36\xf6\xfb\x9a\xf8\xf8\xf6\xf6\x38\xdf\xfb\x9f\xbb\xf8\xf5\x32\xfb\xdf\xdf\x9f\xf8\xf8")); +Time::HiRes::usleep(9000); +snd($sock_b, $port_a, rtp(96, 13, 4160, 0x6543, "\xf1\x70\xcc\x2c\xb0\xbe\x3c\x2b\x21\x51\x80\x0c\x35\xf1\xf0\xef\xf5\x4c\x56\xe1\xad\x13\x8f\x83\x6a\xad\x1f\x1a\xec\x90\x25\x17\x36")); +Time::HiRes::usleep(9000); +rcv($sock_a, $port_b, rtpm(9, 13, 2560, $ssrc, "\x78\x78\x75\xf8\x9e\xde\xb3\xfa\x78\x5e\xf8\xf8\xf8\xf8\xba\xfa\x5e\x72\xde\xb8\xf8\xf5\xf8\xde\x75\x9e\xf8\x75\xb8\xf8\xf7\xba\x5e\xf7\xfa\xfa\x7a\xde\xba\xf7\xfa\x9e\x74\xb4\x74\x7a\x7a\x9b\xba\x74\xf5\xf8\x75\xf3\xdc\xf8\xf8\xde\xb5\xf8\x73\xdf\xb5\x7b\xde\xf8\xde\xf5\xba\xf8\x78\xb8\xfa\xde\xf8\x78\xb7\x7a\xb7\xfa\x5e\xba\xfa\xfa\x5b\xba\x74\xf4\xf5\xf8\xfa\xfa\x9e\x74\xba\x7a\x74\xf4\xba\xfa\xfa\xdb\x74\xf5\xf8\xf8\xf5\xb8\xde\xf8\x77\xde\xba\x7a\x9e\xba\xf2\x5e\x5e\xb4\xf5\xf5\xde\xb5\x75\xf5\xf8\xfa\x78\x9c\xf5\x5c\xf8\xb5\xf5\xf3\xfb\x7b\x5c\xba\xde\xb8\xf5\x78\xb3\xfb\x78\xdc\x9e\x78\xb8\x71\xba\x75\x5c\xf8\xde\xf8\xf3\xdf")); +Time::HiRes::usleep(9000); +snd($sock_b, $port_a, rtp(96, 14, 4480, 0x6543, "\xf1\x70\xcc\x2c\xb0\xbe\x3c\x2b\x21\x51\x80\x0c\x35\xf1\xf0\xef\xf5\x4c\x56\xe1\xad\x13\x8f\x83\x6a\xad\x1f\x1a\xec\x90\x25\x17\x36")); +Time::HiRes::usleep(9000); +rcv($sock_a, $port_b, rtpm(9, 14, 2720, $ssrc, "\xfa\xdc\xf5\x7a\xfa\xba\xf8\xb8\x75\xdc\xf8\xf8\xf3\x7a\xf8\xfa\x9c\xb5\x7a\x9e\xf1\xf5\x75\xdf\x75\x9f\xb8\xf5\x9f\xf5\x36\xfb\xdf\xf8\xb8\xfa\xde\x78\xde\xf5\x78\xb5\xf5\xb8\xf8\x78\x7a\x5c\xb8\xf5\xfa\xf8\xfa\x7a\x7a\xde\xb2\xde\xb5\xf5\x75\x7a\xfa\x9e\xfa\x78\xfa\xfa\x9e\xf4\x77\xde\xb7\xf8\xf5\xf5\xf5\xfa\xfa\xde\x38\xb8\xfa\xf7\xde\xb7\xf8\x7a\xde\xf7\xfa\xb7\xb5\x78\xf8\xdc\x77\xf8\xb7\xf8\xfa\x77\xd9\x7a\xfa\xba\xb7\xf5\xf3\xd7\x5a\xf6\xb8\xdf\xf8\xad\xf9\x5a\x5a\xb6\xbb\x79\xf3\xf7\xdf\xdd\xdf\xfb\xfb\xb6\x76\xdd\xbb\xdd\x79\x9f\xb6\x76\x79\xb9\xf9\x7b\xd8\xfb\xf3\xb6\x5d\xfb\xf9\x5f\xbb\x74\xb4\x7b\x5d\xfb\xdf\xfb\xfb\xf8")); +Time::HiRes::usleep(9000); +# more DTMF +snd($sock_b, $port_a, rtp(97, 15, 4800, 0x6543, "\x02\x07\x01\x40")); +Time::HiRes::usleep(9000); +rcv($sock_a, $port_b, rtpm(101, 15, 2880, $ssrc, "\x02\x07\x00\xa0")); +Time::HiRes::usleep(9000); + +# reverse flow +snd($sock_a, $port_b, rtp(9, 100, 7000, 0x9876, "\xfb\xb8\xde\xde\x71\xb6\xfb\xdf\xf6\xf8\x9a\xfb\xf4\xf4\x78\xf6\x9f\x5f\xb8\xbb\xfb\x78\xf8\xfa\xfa\xb8\xfa\xfa\xf8\x7a\x5e\xb4\xb8\xfa\xb7\x5e\xec\x78\xf8\xba\xde\x78\xba\xde\x78\x73\xde\xb8\xf5\xb5\x7a\xde\xf1\x70\xf6\xdf\xdf\x9f\xfb\xb8\x74\xf6\x76\xdf\xdc\xb8\xdc\x9f\x70\x74\x76\xdf\xdf\x9f\xb8\xfb\x78\x74\xf6\xfb\xdc\xb2\xdc\xdc\x5f\xf4\xf2\xfb\xdd\xb9\xf8\xfb\x9f\xdc\x7b\xb6\xfb\xf8\xf8\x9e\xfa\x78\xdc\xf5\xb8\x75\xb5\xfa\x5c\xf5\xf5\x9f\xf8\xf5\xf5\x76\x9c\x70\x96\xdf\xf9\x76\xf6\xb9\x73\x9b\x7b\xdf\xfb\xf4\xf4\xf7\x9d\xdd\x59\xf7\x77\xb5\xf9\xf9\xb9\xfb\xd9\x77\xf5\xf9\xf7\xb9\xf7\xdd\xdf\xf7\xb9\xf7\x9d\x5f\xf7\xf9\xf9\xf7")); +Time::HiRes::usleep(9000); +($ssrc) = rcv($sock_b, $port_a, rtpm(96, 100, 7000, -1, "\xf1\x54\x54\x3c\x58\x28\x92\xb6\x34\x42\x0b\x59\x8b\x52\x1c\x0d\xa0\xa6\x70\x16\xf8\x9a\x2d\x5e\xf0\x53\xb6\x78\x02\x1d\xff\x54\x12")); +Time::HiRes::usleep(9000); +snd($sock_a, $port_b, rtp(9, 101, 7160, 0x9876, "\xfb\xb8\xde\xde\x71\xb6\xfb\xdf\xf6\xf8\x9a\xfb\xf4\xf4\x78\xf6\x9f\x5f\xb8\xbb\xfb\x78\xf8\xfa\xfa\xb8\xfa\xfa\xf8\x7a\x5e\xb4\xb8\xfa\xb7\x5e\xec\x78\xf8\xba\xde\x78\xba\xde\x78\x73\xde\xb8\xf5\xb5\x7a\xde\xf1\x70\xf6\xdf\xdf\x9f\xfb\xb8\x74\xf6\x76\xdf\xdc\xb8\xdc\x9f\x70\x74\x76\xdf\xdf\x9f\xb8\xfb\x78\x74\xf6\xfb\xdc\xb2\xdc\xdc\x5f\xf4\xf2\xfb\xdd\xb9\xf8\xfb\x9f\xdc\x7b\xb6\xfb\xf8\xf8\x9e\xfa\x78\xdc\xf5\xb8\x75\xb5\xfa\x5c\xf5\xf5\x9f\xf8\xf5\xf5\x76\x9c\x70\x96\xdf\xf9\x76\xf6\xb9\x73\x9b\x7b\xdf\xfb\xf4\xf4\xf7\x9d\xdd\x59\xf7\x77\xb5\xf9\xf9\xb9\xfb\xd9\x77\xf5\xf9\xf7\xb9\xf7\xdd\xdf\xf7\xb9\xf7\x9d\x5f\xf7\xf9\xf9\xf7")); +Time::HiRes::usleep(9000); +rcv($sock_b, $port_a, rtpm(96, 101, 7320, $ssrc, "\xf1\x58\x42\x86\x17\xb7\xe1\xa2\x9c\x79\x5b\x43\x82\x64\xcc\xd1\xe0\xe4\xf8\x67\x69\x3d\x3e\x9e\xd8\x75\x34\xa9\xb2\xa5\x47\x81\x32")); +Time::HiRes::usleep(9000); +snd($sock_a, $port_b, rtp(9, 102, 7320, 0x9876, "\xfb\xb8\xde\xde\x71\xb6\xfb\xdf\xf6\xf8\x9a\xfb\xf4\xf4\x78\xf6\x9f\x5f\xb8\xbb\xfb\x78\xf8\xfa\xfa\xb8\xfa\xfa\xf8\x7a\x5e\xb4\xb8\xfa\xb7\x5e\xec\x78\xf8\xba\xde\x78\xba\xde\x78\x73\xde\xb8\xf5\xb5\x7a\xde\xf1\x70\xf6\xdf\xdf\x9f\xfb\xb8\x74\xf6\x76\xdf\xdc\xb8\xdc\x9f\x70\x74\x76\xdf\xdf\x9f\xb8\xfb\x78\x74\xf6\xfb\xdc\xb2\xdc\xdc\x5f\xf4\xf2\xfb\xdd\xb9\xf8\xfb\x9f\xdc\x7b\xb6\xfb\xf8\xf8\x9e\xfa\x78\xdc\xf5\xb8\x75\xb5\xfa\x5c\xf5\xf5\x9f\xf8\xf5\xf5\x76\x9c\x70\x96\xdf\xf9\x76\xf6\xb9\x73\x9b\x7b\xdf\xfb\xf4\xf4\xf7\x9d\xdd\x59\xf7\x77\xb5\xf9\xf9\xb9\xfb\xd9\x77\xf5\xf9\xf7\xb9\xf7\xdd\xdf\xf7\xb9\xf7\x9d\x5f\xf7\xf9\xf9\xf7")); +Time::HiRes::usleep(9000); +rcv($sock_b, $port_a, rtpm(96, 102, 7640, $ssrc, "\xf1\x50\x42\xfe\x51\x93\xf0\x66\xe8\x59\xeb\xb8\x05\x4a\x5a\x01\xa2\x3d\xf0\x29\x4d\xbd\x9c\x2e\x9f\x2d\x3f\x85\xfa\x1d\x47\x1f\xfa")); +# DTMF +Time::HiRes::usleep(9000); +snd($sock_a, $port_b, rtp(101, 103, 7480, 0x9876, "\x01\x07\x00\xa0")); +Time::HiRes::usleep(9000); +rcv($sock_b, $port_a, rtpm(97, 103, 7960, $ssrc, "\x01\x07\x01\x40")); +Time::HiRes::usleep(9000); +snd($sock_a, $port_b, rtp(101, 104, 7480, 0x9876, "\x01\x07\x01\x40")); +Time::HiRes::usleep(9000); +rcv($sock_b, $port_a, rtpm(97, 104, 7960, $ssrc, "\x01\x07\x02\x80")); +# end +Time::HiRes::usleep(9000); +snd($sock_a, $port_b, rtp(101, 105, 7480, 0x9876, "\x01\x87\x01\xe0")); +Time::HiRes::usleep(1000); +snd($sock_a, $port_b, rtp(101, 106, 7480, 0x9876, "\x01\x87\x01\xe0")); +Time::HiRes::usleep(1000); +snd($sock_a, $port_b, rtp(101, 107, 7480, 0x9876, "\x01\x87\x01\xe0")); +Time::HiRes::usleep(9000); +rcv($sock_b, $port_a, rtpm(97, 105, 7960, $ssrc, "\x01\x87\x03\xc0")); +Time::HiRes::usleep(1000); +rcv($sock_b, $port_a, rtpm(97, 106, 7960, $ssrc, "\x01\x87\x03\xc0")); +Time::HiRes::usleep(1000); +rcv($sock_b, $port_a, rtpm(97, 107, 7960, $ssrc, "\x01\x87\x03\xc0")); +Time::HiRes::usleep(9000); +# more audio +snd($sock_a, $port_b, rtp(9, 108, 7960, 0x9876, "\xfb\xb8\xde\xde\x71\xb6\xfb\xdf\xf6\xf8\x9a\xfb\xf4\xf4\x78\xf6\x9f\x5f\xb8\xbb\xfb\x78\xf8\xfa\xfa\xb8\xfa\xfa\xf8\x7a\x5e\xb4\xb8\xfa\xb7\x5e\xec\x78\xf8\xba\xde\x78\xba\xde\x78\x73\xde\xb8\xf5\xb5\x7a\xde\xf1\x70\xf6\xdf\xdf\x9f\xfb\xb8\x74\xf6\x76\xdf\xdc\xb8\xdc\x9f\x70\x74\x76\xdf\xdf\x9f\xb8\xfb\x78\x74\xf6\xfb\xdc\xb2\xdc\xdc\x5f\xf4\xf2\xfb\xdd\xb9\xf8\xfb\x9f\xdc\x7b\xb6\xfb\xf8\xf8\x9e\xfa\x78\xdc\xf5\xb8\x75\xb5\xfa\x5c\xf5\xf5\x9f\xf8\xf5\xf5\x76\x9c\x70\x96\xdf\xf9\x76\xf6\xb9\x73\x9b\x7b\xdf\xfb\xf4\xf4\xf7\x9d\xdd\x59\xf7\x77\xb5\xf9\xf9\xb9\xfb\xd9\x77\xf5\xf9\xf7\xb9\xf7\xdd\xdf\xf7\xb9\xf7\x9d\x5f\xf7\xf9\xf9\xf7")); +Time::HiRes::usleep(9000); +rcv($sock_b, $port_a, rtpm(96, 108, 8920, $ssrc, "\xf1\x50\x42\x86\xbe\xb7\x49\xe3\x7c\x53\x43\x18\x47\xe1\x6c\x71\xa2\xf6\x76\x20\xcd\x3f\x1f\x7a\x9e\x17\x06\xdc\x72\xf4\xf4\x5f\x7a")); +Time::HiRes::usleep(9000); +snd($sock_a, $port_b, rtp(9, 109, 8120, 0x9876, "\xfb\xb8\xde\xde\x71\xb6\xfb\xdf\xf6\xf8\x9a\xfb\xf4\xf4\x78\xf6\x9f\x5f\xb8\xbb\xfb\x78\xf8\xfa\xfa\xb8\xfa\xfa\xf8\x7a\x5e\xb4\xb8\xfa\xb7\x5e\xec\x78\xf8\xba\xde\x78\xba\xde\x78\x73\xde\xb8\xf5\xb5\x7a\xde\xf1\x70\xf6\xdf\xdf\x9f\xfb\xb8\x74\xf6\x76\xdf\xdc\xb8\xdc\x9f\x70\x74\x76\xdf\xdf\x9f\xb8\xfb\x78\x74\xf6\xfb\xdc\xb2\xdc\xdc\x5f\xf4\xf2\xfb\xdd\xb9\xf8\xfb\x9f\xdc\x7b\xb6\xfb\xf8\xf8\x9e\xfa\x78\xdc\xf5\xb8\x75\xb5\xfa\x5c\xf5\xf5\x9f\xf8\xf5\xf5\x76\x9c\x70\x96\xdf\xf9\x76\xf6\xb9\x73\x9b\x7b\xdf\xfb\xf4\xf4\xf7\x9d\xdd\x59\xf7\x77\xb5\xf9\xf9\xb9\xfb\xd9\x77\xf5\xf9\xf7\xb9\xf7\xdd\xdf\xf7\xb9\xf7\x9d\x5f\xf7\xf9\xf9\xf7")); +Time::HiRes::usleep(9000); +rcv($sock_b, $port_a, rtpm(96, 109, 9240, $ssrc, "\xf1\x58\x43\x82\x36\x15\x27\x26\xb5\x6a\xfb\x25\xc1\x21\x4c\x69\xe5\x76\x06\x4a\xe0\x6e\x9a\xbe\x9c\x87\x52\x8c\xf7\x67\xe5\xa7\xf6")); +# more DTMF +Time::HiRes::usleep(9000); +snd($sock_a, $port_b, rtp(101, 110, 8280, 0x9876, "\x01\x07\x00\xa0")); +Time::HiRes::usleep(9000); +rcv($sock_b, $port_a, rtpm(97, 110, 9560, $ssrc, "\x01\x07\x01\x40")); +Time::HiRes::usleep(9000); +snd($sock_a, $port_b, rtp(101, 111, 8280, 0x9876, "\x01\x07\x01\x40")); +Time::HiRes::usleep(9000); +rcv($sock_b, $port_a, rtpm(97, 111, 9560, $ssrc, "\x01\x07\x02\x80")); diff --git a/t/auto-daemon-tests-reorder.pl b/t/auto-daemon-tests-reorder.pl index c39b5b21e..e8fc65fe3 100755 --- a/t/auto-daemon-tests-reorder.pl +++ b/t/auto-daemon-tests-reorder.pl @@ -2046,1355 +2046,1268 @@ rcv($sock_a, $port_b, rtpm(0, 5000, 7000, -1, "\x00" x 160)); -if ($amr_tests) { -# AMR-WB mode tests -($sock_a, $sock_b) = new_call([qw(198.51.100.10 3000)], [qw(198.51.100.10 3002)]); +new_call; -($port_a) = offer('PCM -> AMR-WB default', - { ICE => 'remove', replace => ['origin'], codec => { transcode => ['AMR-WB'] } }, < 'remove', + flags => ['inject-DTMF'], + codec => {transcode => ['G722']}, + }, < AMR-WB default', - { ICE => 'remove', replace => ['origin'] }, < 'remove', + flags => ['inject-DTMF'], + }, < AMR-WB force bitrate', - { ICE => 'remove', replace => ['origin'], codec => { transcode => ['AMR-WB/16000/1/23850'] } }, < 'remove', + flags => [], + codec => {transcode => ['G722']}, + }, < AMR-WB force bitrate', - { ICE => 'remove', replace => ['origin'] }, < 'remove', + flags => [], + }, < AMR-WB answer mode-set', - { ICE => 'remove', replace => ['origin'], codec => { transcode => ['AMR-WB/16000/1/23850'] } }, < { + mask => ['all'], + transcode => ['G722', 'opus/48000/1', 'PCMA', 'telephone-event'] + }, + }, < AMR-WB answer mode-set', - { ICE => 'remove', replace => ['origin'] }, < AMR-WB offer mode-set', - { ICE => 'remove', replace => ['origin'], codec => { transcode => ['AMR-WB/16000/1/23850//mode-set=0,1,2,3,4,5'] } }, < 'remove', + flags => [], + codec => {transcode => ['G722']}, + }, < AMR-WB offer mode-set', - { ICE => 'remove', replace => ['origin'] }, < 'remove', + flags => [], + }, < AMR-WB offer mode-set, restrict answer', - { ICE => 'remove', replace => ['origin'], codec => { transcode => ['AMR-WB/16000/1/23850//mode-set=0,1,2,3,4,5'] } }, < 'remove', + flags => [], + codec => {transcode => ['G722']}, + }, < AMR-WB offer mode-set, restrict answer', - { ICE => 'remove', replace => ['origin'] }, < 'remove', + flags => [], + }, < PCM default', - { ICE => 'remove', replace => ['origin'], codec => { transcode => ['PCMA'] } }, < 'remove', + flags => [], + codec => {transcode => ['G722']}, + }, < PCM default', - { ICE => 'remove', replace => ['origin'] }, < 'remove', + flags => ['single codec'], + }, < PCM force bitrate', - { ICE => 'remove', replace => ['origin'], codec => { transcode => ['PCMA'], - 'set' => ['AMR-WB/16000/1/23850'] } }, < 'remove', + flags => [], + }, < PCM force bitrate', - { ICE => 'remove', replace => ['origin'] }, < 'remove', + flags => [], + }, < PCM offer mode-set', - { ICE => 'remove', replace => ['origin'], codec => { transcode => ['PCMA'], - 'set' => ['AMR-WB/16000/1/23850'] } }, < 'remove', + flags => [], + }, < PCM offer mode-set', - { ICE => 'remove', replace => ['origin'] }, < 'remove', + flags => ['single codec'], + }, < PCM CMR', - { ICE => 'remove', replace => ['origin'], codec => { transcode => ['PCMA'], - 'set' => ['AMR-WB/16000/1/23850'] } }, < 'remove', + flags => [], + codec => {transcode => ['opus']}, + }, < PCM CMR', - { ICE => 'remove', replace => ['origin'] }, < 'remove', + flags => ['single codec'], + }, < 'remove', replace => ['origin'], codec => { transcode => ['PCMA'], - 'set' => ['AMR-WB/16000/1/23850'] } }, < 'remove', + flags => [], + codec => {mask => ['all'], transcode => ['opus/48000/1', 'PCMA', 'telephone-event']}, + }, < 'remove', replace => ['origin'] }, < 'remove', + flags => ['single codec'], + }, < 'remove', replace => ['origin'], codec => { transcode => ['PCMA'], - 'set' => ['AMR-WB/16000/1/6600'] } }, < 'remove', + flags => [], + codec => {transcode => ['PCMA']}, + }, < 'remove', replace => ['origin'] }, < 'remove', + flags => ["codec-mask-all", "codec-strip-telephone-event", "codec-transcode-PCMU", "codec-transcode-G722", "codec-transcode-t38", "codec-offer-telephone-event", "port-latching"], + 'to-tag' => tt(), + }, < 'remove', replace => ['origin'], codec => { transcode => ['PCMA'], - 'set' => ['AMR-WB/16000/1////CMR-interval=200'] } }, < 'remove', + flags => ["trust-address", "symmetric-codecs"], + }, < 'remove', replace => ['origin'] }, < 'remove', + flags => ["codec-mask-all", "codec-strip-telephone-event", "codec-transcode-PCMU", "codec-transcode-G722", "codec-transcode-t38", "codec-offer-telephone-event", "port-latching"], + 'to-tag' => tt(), + }, < PCM CMR w/ mode-change-interval', - { ICE => 'remove', replace => ['origin'], codec => { transcode => ['PCMA'], - 'set' => ['AMR-WB/16000/1/23850///mode-change-interval=200'] } }, < 'remove', 'transport-protocol' => 'RTP/AVP', + }, < PCM CMR w/ mode-change-interval', - { ICE => 'remove', replace => ['origin'] }, < 'remove', + }, < 'remove', replace => ['origin'], codec => { transcode => ['PCMA'], - 'set' => ['AMR-WB/16000/1/23850///mode-change-interval=200'] } }, < 'remove', 'transport-protocol' => 'RTP/AVP', + 'DTLS-reverse' => 'passive', + }, < 'remove', replace => ['origin'] }, < 'remove', + }, < 'remove', 'transport-protocol' => 'RTP/AVP', 'rtcp-mux' => ['demux'], + }, < 'remove', replace => ['origin'], codec => { - 'transcode' => ['AMR-WB/16000/1/23850//octet-align=1/mode-change-interval=200'] } }, < 'remove', }, < 'remove', replace => ['origin'] }, < 'remove', }, < ft(), blob => $wav_file }); +is $resp->{duration}, 100, 'media duration'; +($seq, $ts, $ssrc) = rcv($sock_a, $port_b, rtpm(8 | 0x80, -1, -1, -1, $pcma_1)); +# SR LEN SSRC NTP1 NTP2 RTP PACKETS OCTETS SSRC LOST SEQ JITTER LAST SR DLSR CNAME +@ret1 = rcv($sock_ax, $port_bx, qr/^\x81\xc8\x00\x0c(.{4})(.{4})(.{4})(.{4})\x00\x00\x00\x01\x00\x00\x00\xac\x00\x00\x12\x34\x00\x00\x00\x00\x00\x00\x03\xe8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81\xca\x00\x05(.{4})\x01\x0c([0-9a-f]{12})\x00\x00$/s); +is $ret1[0], $ssrc, 'SSRC matches'; +is $ret1[3], $ts, 'TS matches'; +is $ret1[4], $ssrc, 'SSRC matches'; -} +rtpe_req('delete', "delete", { 'from-tag' => ft() }); -new_call; -offer('DTMF-inject w tp-e', { - ICE => 'remove', - flags => ['inject-DTMF'], - codec => {transcode => ['G722']}, - }, < 'remove', }, < 'remove', - flags => ['inject-DTMF'], - }, < 'remove', }, < 'remove', - flags => [], - codec => {transcode => ['G722']}, - }, < ft(), blob => $wav_file }); +is $resp->{duration}, 100, 'media duration'; -answer('symmetric codecs w missing answer codec, no flag', { - ICE => 'remove', - flags => [], - }, < ft() }); -new_call; -offer('some t/c options with answer only non-t/c codec', { - codec => { - mask => ['all'], - transcode => ['G722', 'opus/48000/1', 'PCMA', 'telephone-event'] - }, - }, < 'remove', - flags => [], - codec => {transcode => ['G722']}, - }, < 'remove', - flags => [], - }, < 'remove', }, < 'remove', - flags => [], - codec => {transcode => ['G722']}, - }, < 'remove', codec => { mask => ['full'], transcode => ['PCMA','telephone-event'] } }, < 'remove', - flags => [], - }, < 'remove', }, < 'remove', - flags => [], - codec => {transcode => ['G722']}, - }, < 'remove', codec => { mask => ['all'], transcode => ['PCMA','telephone-event'] } }, < 'remove', - flags => ['single codec'], - }, < 'remove', }, < 'remove', - flags => [], - }, < 'remove', codec => { transcode => ['G722'] } }, < 'remove', - flags => [], - }, < 'remove', }, < 'remove', - flags => [], - }, < 'remove', codec => { transcode => ['G722'] } }, < 'remove', - flags => ['single codec'], - }, < 'remove', flags => ['symmetric codecs'] }, < 'remove', - flags => [], - codec => {transcode => ['opus']}, - }, < 'remove', codec => { transcode => ['G722'] } }, < 'remove', - flags => ['single codec'], - }, < 'remove', }, < 'remove', - flags => [], - codec => {mask => ['all'], transcode => ['opus/48000/1', 'PCMA', 'telephone-event']}, - }, < 'remove', codec => { transcode => ['G722'] } }, < 'remove', - flags => ['single codec'], - }, < 'remove', flags => ['symmetric codecs'] }, < 'remove', - flags => [], - codec => {transcode => ['PCMA']}, - }, < 'remove', codec => { transcode => ['G722'] } }, < 'remove', }, < 'remove', - flags => ["codec-mask-all", "codec-strip-telephone-event", "codec-transcode-PCMU", "codec-transcode-G722", "codec-transcode-t38", "codec-offer-telephone-event", "port-latching"], - 'to-tag' => tt(), - }, < 'remove', codec => { transcode => ['G722'] } }, < 'remove', - flags => ["trust-address", "symmetric-codecs"], - }, < 'remove', flags => ['symmetric codecs'] }, < 'remove', - flags => ["codec-mask-all", "codec-strip-telephone-event", "codec-transcode-PCMU", "codec-transcode-G722", "codec-transcode-t38", "codec-offer-telephone-event", "port-latching"], - 'to-tag' => tt(), - }, < [ 'decode' ], ICE => 'remove', + }, < ft() }); -# DTLS-reverse flag -new_call; -offer('DTLS-reverse not set', { - ICE => 'remove', 'transport-protocol' => 'RTP/AVP', - }, < 'remove', + }, < 'remove', - }, < 'remove', + }, < 'remove', 'transport-protocol' => 'RTP/AVP', - 'DTLS-reverse' => 'passive', - }, < 'remove', 'T.38' => [ 'force' ], + }, < 'remove', - }, < 'remove', + }, < ft() }); -# DTLS early start with ICE (GH 1035 TT 84804) -($sock_a, $sock_b, $sock_c, $sock_d) = new_call([qw(198.51.100.4 2000)], [qw(198.51.100.4 2001)], [qw(198.51.100.8 3000)], [qw(198.51.100.8 3001)]); -offer('ICE offer with DTLS', { - ICE => 'remove', 'transport-protocol' => 'RTP/AVP', 'rtcp-mux' => ['demux'], - }, < 'remove', + }, < 'remove', }, < 'remove', + }, < 'remove', }, < 'remove', 'T.38' => [ 'decode' ], + }, < ft(), blob => $wav_file }); -is $resp->{duration}, 100, 'media duration'; - -($seq, $ts, $ssrc) = rcv($sock_a, $port_b, rtpm(8 | 0x80, -1, -1, -1, $pcma_1)); -# SR LEN SSRC NTP1 NTP2 RTP PACKETS OCTETS SSRC LOST SEQ JITTER LAST SR DLSR CNAME -@ret1 = rcv($sock_ax, $port_bx, qr/^\x81\xc8\x00\x0c(.{4})(.{4})(.{4})(.{4})\x00\x00\x00\x01\x00\x00\x00\xac\x00\x00\x12\x34\x00\x00\x00\x00\x00\x00\x03\xe8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81\xca\x00\x05(.{4})\x01\x0c([0-9a-f]{12})\x00\x00$/s); -is $ret1[0], $ssrc, 'SSRC matches'; -is $ret1[3], $ts, 'TS matches'; -is $ret1[4], $ssrc, 'SSRC matches'; +answer('T.38 reverse re-invite', { ICE => 'remove' }, < ft() }); @@ -4022,2602 +4005,995 @@ rtpe_req('delete', "delete", { 'from-tag' => ft() }); -($sock_a, $sock_ax, $sock_b, $sock_bx) = new_call( - [qw(198.51.100.1 7400)], - [qw(198.51.100.1 7401)], - [qw(198.51.100.3 7402)], - [qw(198.51.100.3 7403)], -); -($port_a, $port_ax) = offer('RTCP player w/ previous SR', { ICE => 'remove', }, < 'remove', + }, < 'remove', }, < 'remove', + }, < 'remove', 'T.38' => [ 'force' ], + }, < 'remove', + }, < ft(), blob => $wav_file }); -is $resp->{duration}, 100, 'media duration'; - -($seq, $ts, $ssrc) = rcv($sock_a, $port_b, rtpm(8 | 0x80, -1, -1, -1, $pcma_1)); -# SR LEN SSRC NTP1 NTP2 RTP PACKETS OCTETS SSRC LOST SEQ JITTER LAST SR DLSR CNAME -@ret1 = rcv($sock_ax, $port_bx, qr/^\x81\xc8\x00\x0c(.{4})(.{4})(.{4})(.{4})\x00\x00\x00\x01\x00\x00\x00\xac\x00\x00\x12\x34\x00\x00\x00\x00\x00\x00\x03\xe8\x00\x00\x00\x00\x56\x78\x9a\xbc(.{4})\x81\xca\x00\x05(.{4})\x01\x0c([0-9a-f]{12})\x00\x00$/s); -is $ret1[0], $ssrc, 'SSRC matches'; -is $ret1[3], $ts, 'TS matches'; -cmp_ok $ret1[4], '<', 1000, 'DSLR ok'; -is $ret1[5], $ssrc, 'SSRC matches'; - -rtpe_req('delete', "delete", { 'from-tag' => ft() }); +rtpe_req('delete', "delete", { 'from-tag' => ft() }); -# MSRP (GH 959) - new_call(); -offer('gh 959 media c=', { ICE => 'remove', }, < 'remove', + }, < 'remove', + }, < 'remove', 'T.38' => [ 'decode' ], + }, < 'remove', }, < 'remove' }, < ft() }); +new_call; - - -# PT collisions (GH 963) - -new_call(); - -offer('gh 963', { ICE => 'remove', codec => { mask => ['full'], transcode => ['PCMA','telephone-event'] } }, < 'remove', 'T.38' => [ 'force', 'FEC' ], + }, < 'remove', }, < ft() }); -new_call(); -offer('gh 963 w mask all', { ICE => 'remove', codec => { mask => ['all'], transcode => ['PCMA','telephone-event'] } }, < 'remove', }, < 'force-relay', flags => [qw(SDES-off)], 'transport-protocol' => 'UDP/TLS/RTP/SAVPF', + 'rtcp-mux' => [qw(accept offer)], 'via-branch' => 'z9hG4bK9463.af303705.113', + }, < 'remove', codec => { transcode => ['G722'] } }, < 'remove', }, < 'remove', codec => { transcode => ['G722'] } }, < 'remove', flags => ['symmetric codecs'] }, < 'remove', codec => { transcode => ['G722'] } }, < 'remove', }, < 'remove', codec => { transcode => ['G722'] } }, < 'remove', flags => ['symmetric codecs'] }, < 'remove', codec => { transcode => ['G722'] } }, < 'remove', }, < 'remove', codec => { transcode => ['G722'] } }, < 'remove', flags => ['symmetric codecs'] }, < [ 'decode' ], ICE => 'remove', - }, < ft() }); - - - - - - -new_call(); - -offer('T.38 forward re-invite', { ICE => 'remove', - }, < 'remove', - }, < 'remove', 'T.38' => [ 'force' ], - }, < 'remove', - }, < ft() }); - - - - -new_call(); - -offer('T.38 reverse re-invite', { ICE => 'remove', - }, < 'remove', - }, < 'remove', 'T.38' => [ 'decode' ], - }, < 'remove' }, < ft() }); - - - - - - -new_call(); - -offer('T.38 forward re-invite w/ unsupported codec', { ICE => 'remove', - }, < 'remove', - }, < 'remove', 'T.38' => [ 'force' ], - }, < 'remove', - }, < ft() }); - - - - -new_call(); - -offer('T.38 reverse re-invite w/ unsupported codec', { ICE => 'remove', - }, < 'remove', - }, < 'remove', 'T.38' => [ 'decode' ], - }, < 'remove' }, < ft() }); - - - -new_call; - -offer('T.38 FEC invite', { ICE => 'remove', 'T.38' => [ 'force', 'FEC' ], - }, < ft() }); - - - - - -# github issue 850 - -new_call; - -@ret1 = offer('gh 850', - { - ICE => 'force-relay', flags => [qw(SDES-off)], 'transport-protocol' => 'UDP/TLS/RTP/SAVPF', - 'rtcp-mux' => [qw(accept offer)], 'via-branch' => 'z9hG4bK9463.af303705.113', - }, < 'force-relay', flags => [qw(SDES-off)], 'transport-protocol' => 'UDP/TLS/RTP/SAVPF', - 'rtcp-mux' => [qw(accept offer)], 'via-branch' => 'z9hG4bK9463.af303705.113', - }, < 'remove', replace => ['origin'], codec => { transcode => ['PCMA'] } }, < 'remove', replace => ['origin'] }, < 'remove', replace => ['origin'], codec => { transcode => ['PCMA'] } }, < 'remove', replace => ['origin'] }, < 'remove', replace => ['origin'], flags => ['inject DTMF'] }, < 'remove', replace => ['origin'], flags => ['inject DTMF'] }, < ft(), code => '0', volume => 10, duration => 100 }); - -snd($sock_a, $port_b, rtp(0, 1002, 3320, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(96 | 0x80, 1002, 3320, $ssrc, "\x00\x0a\x00\xa0")); -snd($sock_a, $port_b, rtp(0, 1003, 3480, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(96, 1003, 3320, $ssrc, "\x00\x0a\x01\x40")); -snd($sock_a, $port_b, rtp(0, 1004, 3640, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(96, 1004, 3320, $ssrc, "\x00\x0a\x01\xe0")); -snd($sock_a, $port_b, rtp(0, 1005, 3800, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(96, 1005, 3320, $ssrc, "\x00\x0a\x02\x80")); -snd($sock_a, $port_b, rtp(0, 1006, 3960, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(96, 1006, 3320, $ssrc, "\x00\x0a\x03\x20")); -snd($sock_a, $port_b, rtp(0, 1007, 4120, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(96, 1007, 3320, $ssrc, "\x00\x8a\x03\xc0")); -rcv($sock_b, $port_a, rtpm(96, 1008, 3320, $ssrc, "\x00\x8a\x03\xc0")); -rcv($sock_b, $port_a, rtpm(96, 1009, 3320, $ssrc, "\x00\x8a\x03\xc0")); -snd($sock_a, $port_b, rtp(0, 1008, 4280, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1010, 4280, $ssrc, "\x00" x 160)); - - - -snd($sock_b, $port_a, rtp(0, 4000, 8000, 0x6543, "\x00" x 160)); -($ssrc) = rcv($sock_a, $port_b, rtpm(0, 4000, 8000, -1, "\x00" x 160)); -snd($sock_b, $port_a, rtp(0, 4001, 8160, 0x6543, "\x00" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4001, 8160, $ssrc, "\x00" x 160)); - -$resp = rtpe_req('play DTMF', 'inject DTMF towards A', - { 'from-tag' => tt(), code => '*', volume => 10, duration => 100 }); - -snd($sock_b, $port_a, rtp(0, 4002, 8320, 0x6543, "\x00" x 160)); -rcv($sock_a, $port_b, rtpm(96 | 0x80, 4002, 8320, $ssrc, "\x0a\x0a\x00\xa0")); -snd($sock_b, $port_a, rtp(0, 4003, 8480, 0x6543, "\x00" x 160)); -rcv($sock_a, $port_b, rtpm(96, 4003, 8320, $ssrc, "\x0a\x0a\x01\x40")); -snd($sock_b, $port_a, rtp(0, 4004, 8640, 0x6543, "\x00" x 160)); -rcv($sock_a, $port_b, rtpm(96, 4004, 8320, $ssrc, "\x0a\x0a\x01\xe0")); -snd($sock_b, $port_a, rtp(0, 4005, 8800, 0x6543, "\x00" x 160)); -rcv($sock_a, $port_b, rtpm(96, 4005, 8320, $ssrc, "\x0a\x0a\x02\x80")); -snd($sock_b, $port_a, rtp(0, 4006, 8960, 0x6543, "\x00" x 160)); -rcv($sock_a, $port_b, rtpm(96, 4006, 8320, $ssrc, "\x0a\x0a\x03\x20")); -snd($sock_b, $port_a, rtp(0, 4007, 9120, 0x6543, "\x00" x 160)); -rcv($sock_a, $port_b, rtpm(96, 4007, 8320, $ssrc, "\x0a\x8a\x03\xc0")); -rcv($sock_a, $port_b, rtpm(96, 4008, 8320, $ssrc, "\x0a\x8a\x03\xc0")); -rcv($sock_a, $port_b, rtpm(96, 4009, 8320, $ssrc, "\x0a\x8a\x03\xc0")); -snd($sock_b, $port_a, rtp(0, 4008, 9280, 0x6543, "\x00" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4010, 9280, $ssrc, "\x00" x 160)); - - - - - -# transcoding, RFC payload type present on both sides - -($sock_a, $sock_b) = new_call([qw(198.51.100.1 6110)], [qw(198.51.100.3 6112)]); - -($port_a) = offer('transcoding, RFC payload type present on both sides', - { ICE => 'remove', replace => ['origin'], flags => ['inject DTMF'], - codec => { transcode => ['PCMA'] }}, < 'remove', replace => ['origin'], flags => ['inject DTMF'] }, < ft(), code => '0', volume => 10, duration => 100 }); - -snd($sock_a, $port_b, rtp(0, 1002, 3320, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(96 | 0x80, 1002, 3320, $ssrc, "\x00\x0a\x00\xa0")); -snd($sock_a, $port_b, rtp(0, 1003, 3480, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(96, 1003, 3320, $ssrc, "\x00\x0a\x01\x40")); -snd($sock_a, $port_b, rtp(0, 1004, 3640, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(96, 1004, 3320, $ssrc, "\x00\x0a\x01\xe0")); -snd($sock_a, $port_b, rtp(0, 1005, 3800, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(96, 1005, 3320, $ssrc, "\x00\x0a\x02\x80")); -snd($sock_a, $port_b, rtp(0, 1006, 3960, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(96, 1006, 3320, $ssrc, "\x00\x0a\x03\x20")); -snd($sock_a, $port_b, rtp(0, 1007, 4120, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(96, 1007, 3320, $ssrc, "\x00\x8a\x03\xc0")); -rcv($sock_b, $port_a, rtpm(96, 1008, 3320, $ssrc, "\x00\x8a\x03\xc0")); -rcv($sock_b, $port_a, rtpm(96, 1009, 3320, $ssrc, "\x00\x8a\x03\xc0")); -snd($sock_a, $port_b, rtp(0, 1008, 4280, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(8, 1010, 4280, $ssrc, "\x2a" x 160)); - - - -snd($sock_b, $port_a, rtp(8, 4000, 8000, 0x6543, "\x2a" x 160)); -($ssrc) = rcv($sock_a, $port_b, rtpm(0, 4000, 8000, -1, "\x00" x 160)); -snd($sock_b, $port_a, rtp(8, 4001, 8160, 0x6543, "\x2a" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4001, 8160, $ssrc, "\x00" x 160)); - -$resp = rtpe_req('play DTMF', 'inject DTMF towards A', - { 'from-tag' => tt(), code => '#', volume => -10, duration => 100 }); - -snd($sock_b, $port_a, rtp(8, 4002, 8320, 0x6543, "\x2a" x 160)); -rcv($sock_a, $port_b, rtpm(96 | 0x80, 4002, 8320, $ssrc, "\x0b\x0a\x00\xa0")); -snd($sock_b, $port_a, rtp(8, 4003, 8480, 0x6543, "\x2a" x 160)); -rcv($sock_a, $port_b, rtpm(96, 4003, 8320, $ssrc, "\x0b\x0a\x01\x40")); -snd($sock_b, $port_a, rtp(8, 4004, 8640, 0x6543, "\x2a" x 160)); -rcv($sock_a, $port_b, rtpm(96, 4004, 8320, $ssrc, "\x0b\x0a\x01\xe0")); -snd($sock_b, $port_a, rtp(8, 4005, 8800, 0x6543, "\x2a" x 160)); -rcv($sock_a, $port_b, rtpm(96, 4005, 8320, $ssrc, "\x0b\x0a\x02\x80")); -snd($sock_b, $port_a, rtp(8, 4006, 8960, 0x6543, "\x2a" x 160)); -rcv($sock_a, $port_b, rtpm(96, 4006, 8320, $ssrc, "\x0b\x0a\x03\x20")); -snd($sock_b, $port_a, rtp(8, 4007, 9120, 0x6543, "\x2a" x 160)); -rcv($sock_a, $port_b, rtpm(96, 4007, 8320, $ssrc, "\x0b\x8a\x03\xc0")); -rcv($sock_a, $port_b, rtpm(96, 4008, 8320, $ssrc, "\x0b\x8a\x03\xc0")); -rcv($sock_a, $port_b, rtpm(96, 4009, 8320, $ssrc, "\x0b\x8a\x03\xc0")); -snd($sock_b, $port_a, rtp(8, 4008, 9280, 0x6543, "\x2a" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4010, 9280, $ssrc, "\x00" x 160)); - - - -# no transcoding, no RFC payload type present - -($sock_a, $sock_b) = new_call([qw(198.51.100.1 6014)], [qw(198.51.100.3 6016)]); - -($port_a) = offer('no transcoding, no RFC payload type present', - { ICE => 'remove', replace => ['origin'], flags => ['inject DTMF'] }, < 'remove', replace => ['origin'], flags => ['inject DTMF'] }, < ft(), code => 'C', volume => 5, duration => 120, pause => 110 }); - -snd($sock_a, $port_b, rtp(0, 1002, 3320, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1002, 3320, $ssrc, "\xff\x93\x94\xbc\x2e\x56\xbf\x2b\x13\x1b\xa7\x8e\x98\x47\x25\x41\xe2\x24\x16\x2b\x99\x8e\x9f\x28\x1e\x3d\x5b\x23\x1c\xdf\x92\x8f\xb6\x1c\x1c\x40\x5d\x26\x25\xaa\x8f\x95\x3b\x15\x1d\x5e\xde\x2c\x38\x9d\x8f\x9e\x1f\x11\x20\xc0\xc1\x37\xdd\x99\x92\xb7\x15\x10\x2c\xac\xb5\x49\xb8\x97\x99\x37\x0f\x13\x58\xa0\xae\x67\xae\x99\xa4\x1f\x0d\x1a\xae\x9b\xad\x7b\xad\x9d\xbf\x16\x0e\x27\x9d\x98\xb0\x55\xb1\xa6\x3a\x11\x11\x63\x95\x98\xbf\x3e\xbb\xb4\x26\x10\x1a\xa9\x90\x9a\x4e\x30\xce\xd4\x1e\x12\x29\x99\x8e\xa1\x2d\x29\x6d\x4b\x1c\x18\xef\x91\x8f\xb6\x1f\x24\x57\x3e\x1d\x20\xa9\x8e\x95\x3e\x19\x23\x67\x3e\x21\x31\x9c\x8e\x9e\x22\x14\x26\xcd\x4a")); -snd($sock_a, $port_b, rtp(0, 1003, 3480, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1003, 3480, $ssrc, "\x2a\xdf\x96\x90\xb5\x17\x13\x2f\xb6\xf5\x36\xb1\x93\x96\x39\x10\x15\x55\xaa\xc8\x4c\xa7\x95\xa0\x1f\x0e\x1b\xb4\xa1\xbd\xed\xa4\x99\xbb\x15\x0e\x27\xa0\x9d\xbd\xda\xa4\x9f\x39\x10\x11\x58\x98\x9c\xc8\xf9\xa9\xac\x23\x0e\x19\xab\x92\x9e\x59\x4c\xb0\xca\x1b\x10\x27\x9a\x90\xa5\x35\x3a\xbe\x43\x18\x15\x6c\x92\x91\xb7\x26\x30\xd6\x32\x18\x1d\xa9\x8e\x96\x44\x1d\x2d\xfc\x2e\x1b\x2d\x9a\x8d\x9e\x25\x19\x2d\xe7\x2f\x20\xea\x94\x8f\xb3\x19\x17\x36\xc8\x36\x2c\xae\x90\x95\x3b\x12\x18\x55\xb7\x43\x3e\xa1\x91\x9e\x1f\x0f\x1d\xba\xac\x64\xe8\x9d\x95\xb7\x15\x0e\x29\xa6\xa6\xda\xc3\x9d\x9b\x39\x0f\x11\x51\x9c\xa2\xd8\xbe\x9f\xa7\x21\x0e\x18\xad")); -snd($sock_a, $port_b, rtp(0, 1004, 3640, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1004, 3640, $ssrc, "\x96\xa3\x68\xc4\xa5\xc2\x19\x0e\x26\x9c\x93\xa9\x3f\xdb\xae\x3e\x14\x12\x5b\x93\x93\xb9\x2e\x51\xbe\x2c\x14\x1b\xa9\x8f\x97\x4c\x25\x3f\xde\x25\x16\x2a\x9a\x8e\x9e\x29\x1e\x3b\x5e\x24\x1b\x7b\x92\x8f\xb2\x1c\x1c\x3e\x61\x27\x25\xac\x8f\x94\x3e\x15\x1c\x59\xdb\x2d\x37\x9e\x8f\x9d\x20\x11\x1f\xc2\xbf\x38\xea\x99\x92\xb4\x16\x10\x2b\xad\xb4\x49\xba\x98\x98\x3a\x0f\x12\x4e\xa1\xad\x68\xaf\x99\xa3\x20\x0d\x19\xb0\x9b\xac\x7b\xae\x9d\xbc\x17\x0e\x25\x9e\x98\xaf\x55\xb2\xa6\x3d\x12\x11\x52\x96\x97\xbd\x3e\xbc\xb3\x28\x10\x19\xab\x90\x9a\x54\x2f\xd0\xcf\x1f\x12\x27\x9a\x8e\xa0\x2e\x28\x66\x4e\x1d\x18\x62\x92\x8f\xb2\x20\x23\x53\x3f\x1d\x1f")); -snd($sock_a, $port_b, rtp(0, 1005, 3800, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1005, 3800, $ssrc, "\xab\x8e\x94\x44\x19\x22\x61\x40\x21\x2f\x9c\x8e\x9d\x23\x14\x25\xce\x4d\x2a\xf7\x96\x8f\xb1\x18\x13\x2e\xb7\xe8\x36\xb3\x94\x96\x3c\x10\x15\x4d\xaa\xc5\x4b\xa8\x95\x9f\x20\x0e\x1a\xb6\xa0\xbc\xf5\xa4\x99\xb8\x16\x0e\x26\xa1\x9d\xbb\xdd\xa5\x9f\x3c\x10\x10\x4c\x99\x9b\xc5\x78\xaa\xac\x24\x0f\x18\xac\x93\x9d\x5f\x4a\xb1\xc7\x1c\x0f\x25\x9b\x90\xa3\x36\x39\xbf\x47\x18\x14\x56\x92\x90\xb4\x27\x2f\xd7\x34\x18\x1c\xab\x8e\x95\x4b\x1d\x2c\xfe\x2f\x1b\x2c\x9b\x8d\x9d\x27\x19\x2c\xe7\x30\x20\x6d\x94\x8f\xaf\x1a\x17\x34\xc8\x37\x2b\xaf\x91\x94\x3f\x12\x18\x4e\xb6\x45\x3d\xa3\x91\x9e\x20\x0f\x1c\xbc\xab\x6c\xf5\x9e\x95\xb3\x16\x0e\x27\xa7\xa5")); -snd($sock_a, $port_b, rtp(0, 1006, 3960, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1006, 3960, $ssrc, "\xd6\xc6\x9d\x9b\x3d\x0f\x11\x49\x9c\xa1\xd4\xbf\x9f\xa6\x22\x0e\x18\xaf\x96\xa2\x6e\xc6\xa5\xbe\x19\x0e\x24\x9d\x93\xa8\x40\xe1\xae\x42\x15\x12\x4e\x94\x93\xb7\x2e\x4e\xbe\x2d\x14\x1a\xab\x8f\x97\x52\x25\x3e\xdc\x26\x16\x28\x9b\x8e\x9e\x2b\x1e\x3a\x61\x25\x1b\x5d\x93\x8f\xaf\x1d\x1c\x3d\x67\x27\x24\xad\x8f\x93\x45\x15\x1c\x53\xd7\x2d\x35\x9f\x8f\x9c\x22\x11\x1f\xc5\xbe\x38\x7a\x9a\x91\xb0\x17\x10\x29\xad\xb3\x4a\xbc\x98\x98\x3e\x10\x12\x48\xa1\xad\x6a\xb1\x9a\xa1\x21\x0e\x18\xb3\x9b\xab\x7d\xaf\x9d\xb9\x18\x0e\x23\x9f\x97\xae\x55\xb4\xa5\x40\x12\x10\x49\x96\x97\xbb\x3d\xbd\xb2\x29\x10\x18\xac\x90\x99\x5d\x2f\xd4\xcd\x1f\x12\x25\x9b")); -snd($sock_a, $port_b, rtp(0, 1007, 4120, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1007, 4120, $ssrc, "\x8e\x9f\x2f\x28\x5f\x51\x1d\x17\x52\x92\x8f\xaf\x20\x22\x50\x42\x1e\x1f\xad\x8e\x93\x4b\x19\x21\x5d\x42\x22\x2e\x9d\x8e\x9c\x25\x14\x24\xd0\x4f\x2a\x68\x97\x8f\xae\x18\x12\x2c\xb7\xdf\x36\xb6\x94\x95\x41\x11\x14\x48\xaa\xc3\x4a\xaa\x95\x9e\x21\x0e\x19\xb8\xa0\xba\xfe\xa5\x99\xb4\x17\x0e\x24\xa2\x9c\xba\xe0\xa6\x9e\x40\x10\x10\x45\x99\x9b\xc2\x6d\xaa\xab\x26\x0f\x17\xae\x93\x9c\x6a\x48\xb2\xc3\x1c\x0f\x23\x9c\x90\xa2\x37\x38\xbf\x4b\x19\x14\x4b\x93\x90\xb1\x27\x2e\xd8\x36\x19\x1c\xad\x8e\x94\x52\x1d\x2b\x7d\x30\x1b\x2a\x9c\x8d\x9c\x28\x19\x2b\xe7\x31\x20\x5a\x95\x8f\xad\x1a\x16\x32\xc8\x39\x2b\xb2\x91\x94\x46\x13\x17\x4a\xb6\x48\x3c")); -# pause -snd($sock_a, $port_b, rtp(0, 1008, 4280, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1008, 4280, $ssrc, "\xff" x 160)); -snd($sock_a, $port_b, rtp(0, 1009, 4440, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1009, 4440, $ssrc, "\xff" x 160)); -snd($sock_a, $port_b, rtp(0, 1010, 4600, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1010, 4600, $ssrc, "\xff" x 160)); -snd($sock_a, $port_b, rtp(0, 1011, 4760, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1011, 4760, $ssrc, "\xff" x 160)); -snd($sock_a, $port_b, rtp(0, 1012, 4920, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1012, 4920, $ssrc, "\xff" x 160)); -snd($sock_a, $port_b, rtp(0, 1013, 5080, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1013, 5080, $ssrc, "\xff" x 80 . "\x00" x 80)); - - - -snd($sock_b, $port_a, rtp(0, 4000, 8000, 0x6543, "\x00" x 160)); -($ssrc) = rcv($sock_a, $port_b, rtpm(0, 4000, 8000, -1, "\x00" x 160)); -snd($sock_b, $port_a, rtp(0, 4001, 8160, 0x6543, "\x00" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4001, 8160, $ssrc, "\x00" x 160)); - -$resp = rtpe_req('play DTMF', 'inject DTMF towards A', - { 'from-tag' => tt(), code => '4', volume => 3, duration => 150, pause => 100 }); - -snd($sock_b, $port_a, rtp(0, 4002, 8320, 0x6543, "\x00" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4002, 8320, $ssrc, "\xff\x90\x8a\x93\xd9\x1b\x18\x27\x65\xe5\x33\x29\x4c\x9e\x8f\x91\xb8\x15\x09\x0d\x32\x98\x8e\x96\xbb\x2c\x2b\x4c\xd8\x34\x1c\x18\x2e\x9d\x8c\x8c\xa5\x1a\x0b\x0d\x27\xa3\x97\x9e\xbd\x4f\xc4\xaa\xb2\x2c\x12\x0e\x1e\xa1\x8b\x8a\x9c\x25\x0e\x10\x25\xb7\xa7\xb7\x5e\xcb\xa2\x98\x9f\x30\x0f\x0a\x16\xae\x8d\x8a\x98\x3a\x18\x19\x2c\xdd\xfd\x30\x2b\xce\x99\x8e\x95\x4c\x0f\x09\x10\xdf\x93\x8e\x9a\xec\x28\x2c\x56\xee\x2d\x1a\x1a\x48\x97\x8b\x8e\xba\x14\x0a\x0f\x39\x9d\x96\xa1\xcd\x4e\xbe\xab\xbe\x23\x10\x10\x2b\x99\x8a\x8c\xa7\x1b\x0d\x12\x2f\xad\xa7\xbc\x5e\xbd\x9f\x99\xa8\x23\x0d\x0b\x1d\x9f\x8b\x8c\x9f\x29\x16\x1b\x34\xcd\x60\x2f\x2f\xb6\x96")); -snd($sock_b, $port_a, rtp(0, 4003, 8480, 0x6543, "\x00" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4003, 8480, $ssrc, "\x8e\x9b\x2b\x0c\x09\x17\xae\x8f\x8e\x9e\x3f\x25\x2e\x65\x5c\x28\x1a\x1e\xc2\x92\x8a\x92\x44\x0f\x0a\x14\xd6\x99\x97\xa6\x7c\x4e\xba\xad\xe5\x1d\x0f\x13\x49\x92\x89\x8e\xbe\x15\x0d\x16\x43\xa8\xa7\xc1\x66\xb5\x9d\x9a\xb6\x1b\x0c\x0d\x2b\x98\x8a\x8d\xab\x1f\x15\x1d\x3f\xc7\x52\x2e\x39\xaa\x93\x8f\xa3\x1e\x0b\x0b\x1e\x9f\x8d\x8f\xa7\x30\x23\x31\x7c\x4a\x24\x1a\x24\xac\x8e\x8b\x99\x28\x0c\x0a\x1a\xb0\x96\x98\xac\x4f\x53\xb7\xaf\x44\x19\x0f\x18\xba\x8e\x89\x93\x3f\x10\x0d\x1a\xd5\xa3\xa8\xca\xf9\xae\x9c\x9d\xec\x16\x0b\x10\x4e\x91\x89\x90\xc6\x1a\x14\x20\x55\xc3\x4a\x2f\x49\xa2\x91\x92\xb2\x17\x09\x0c\x2d\x99\x8d\x92\xb3\x29\x23\x36\xf2")); -snd($sock_b, $port_a, rtp(0, 4004, 8640, 0x6543, "\x00" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4004, 8640, $ssrc, "\x3e\x20\x1b\x2d\xa0\x8d\x8c\xa1\x1c\x0a\x0c\x22\xa3\x94\x9a\xb5\x44\x5c\xb5\xb6\x32\x16\x0f\x1e\xa6\x8c\x8a\x99\x28\x0e\x0e\x20\xb7\xa1\xab\xd4\xdb\xaa\x9c\xa1\x38\x11\x0b\x15\xb5\x8d\x8a\x96\x3f\x16\x15\x26\xdd\xc2\x43\x31\xdf\x9d\x90\x96\x6d\x11\x09\x0f\x5a\x93\x8c\x97\xd2\x23\x23\x3b\xf6\x37\x1f\x1d\x40\x9a\x8c\x8e\xb2\x15\x09\x0e\x31\x9c\x93\x9c\xc2\x3e\x74\xb4\xbf\x29\x14\x11\x29\x9b\x8a\x8b\xa3\x1c\x0d\x0f\x2a\xab\x9f\xad\xe0\xcc\xa6\x9c\xa9\x28\x0e\x0c\x1c\xa2\x8b\x8b\x9c\x2a\x14\x17\x2c\xc6\xc4\x3e\x36\xbd\x99\x90\x9b\x30\x0d\x09\x15\xb3\x8f\x8d\x9b\x42\x1f\x25\x42\x70\x30\x1e\x1f\xcf\x95\x8b\x92\x58\x0f\x09\x12\x6f\x98\x93")); -snd($sock_b, $port_a, rtp(0, 4005, 8800, 0x6543, "\x00" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4005, 8800, $ssrc, "\x9f\xe5\x3b\xe2\xb5\xd9\x21\x12\x14\x3e\x95\x89\x8d\xb6\x16\x0c\x13\x3a\xa4\x9f\xb1\xf1\xc0\xa3\x9d\xb4\x1e\x0d\x0d\x27\x99\x8a\x8c\xa7\x1f\x12\x19\x37\xbc\xc8\x3c\x3c\xaf\x97\x91\xa2\x21\x0b\x0a\x1c\xa2\x8d\x8e\xa2\x2f\x1e\x28\x4c\x5d\x2c\x1e\x25\xb0\x90\x8c\x98\x2c\x0c\x0a\x18\xb4\x94\x94\xa6\x4d\x3a\xd4\xb8\x4f\x1d\x11\x18\xc5\x8f\x89\x91\x4d\x10\x0c\x17\xec\x9f\xa0\xb8\xff\xba\xa1\x9f\xd3\x19\x0c\x0f\x3f\x92\x89\x8f\xbb\x19\x11\x1c\x48\xb8\xce\x3b\x4a\xa8\x95\x93\xaf\x19\x0a\x0c\x29\x99\x8c\x8f\xad\x27\x1d\x2b\x59\x4f\x29\x1e\x2d\xa5\x8e\x8d\x9f\x1e\x0b\x0b\x1e\xa4\x91\x96\xad\x3e\x3b\xcc\xbc\x3a\x1a\x12\x1e\xaa\x8d\x8a\x98\x2b")); -snd($sock_b, $port_a, rtp(0, 4006, 8960, 0x6543, "\x00" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4006, 8960, $ssrc, "\x0e\x0c\x1d\xb8\x9d\xa2\xbe\xf9\xb4\xa0\xa3\x3f\x14\x0c\x14\xbd\x8e\x89\x93\x49\x15\x12\x1f\xe7\xb5\xd9\x3c\x7c\xa1\x93\x97\xd5\x13\x09\x0e\x45\x93\x8b\x93\xc4\x20\x1d\x2e\x6b\x46\x26\x1f\x3d\x9d\x8d\x8e\xae\x17\x09\x0d\x2c\x9c\x90\x98\xba\x36\x3d\xc7\xc4\x2e\x17\x13\x27\x9e\x8b\x8b\x9f\x1e\x0c\x0e\x25\xaa\x9c\xa5\xc8\xe8\xae\xa0\xaa\x2d\x10\x0c\x1b\xa6\x8c\x8a\x9a\x2c\x12\x13\x27\xc3\xb3\xed\x3e\xc8\x9d\x93\x9b\x38\x0f\x09\x13\xba\x8f\x8b\x98\x4a\x1d\x1e\x34\xf9\x3e\x24\x23\xea\x98\x8c\x92\xdf\x10\x09\x0f\x4d\x97\x90\x9c\xd2\x31\x3f\xc5\xd6\x28\x16\x16\x39\x97\x8a\x8d\xaf\x17\x0b\x10\x32\xa2\x9b\xa8\xd6\xd9\xac\xa1\xb3\x22\x0e\x0e")); -snd($sock_b, $port_a, rtp(0, 4007, 9120, 0x6543, "\x00" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4007, 9120, $ssrc, "\x24\x9b\x8a\x8b\xa2\x1f\x10\x15\x2f\xb8\xb4\x68\x43\xb8\x9a\x94\xa1\x25\x0c\x0a\x1a\xa5\x8d\x8c\x9e\x30\x1b\x1f\x3c\xee\x38\x23\x28\xb8\x93\x8d\x97\x31\x0d\x09\x15\xb9\x93\x90\xa0\x4f\x2f\x46\xc4\x5e\x21\x15\x19\xd7\x91\x89\x90\x7b\x10\x0b\x14\x5b\x9d\x9c\xad\xed\xcd\xa9\xa3\xca\x1c\x0d\x10\x38\x94\x89\x8e\xb3\x19\x0f\x18\x3e\xb0\xb5\x59\x4d\xae\x98\x95\xad\x1c\x0b\x0c\x25\x9b\x8b\x8e\xa9\x26\x1a\x22\x46\xf5\x33\x23\x2e\xaa\x90\x8d\x9e\x21\x0b\x0a\x1c\xa6\x90\x92\xa8\x3b\x2e\x4d\xc7\x43\x1e\x15\x1e\xaf\x8e\x8a\x96\x2e\x0e\x0b\x1a\xbb\x9b\x9d\xb2\x68\xc5\xa8\xa7\x4c\x17\x0d\x14\xcb\x8f\x89\x91\x5e\x14\x0f\x1c\x6e\xad\xb8\x52\x68\xa8")); -snd($sock_b, $port_a, rtp(0, 4008, 9280, 0x6543, "\x00" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4008, 9280, $ssrc, "\x97\x98\xc7\x16\x0a\x0e\x3a\x94\x8a\x90\xbb\x1e\x1a\x27\x56\x6f\x2f\x25\x3b\xa0\x8e\x8f\xaa\x19\x09\x0c\x28\x9c\x8f\x95\xb2\x31\x2e\x59\xcc\x37\x1b\x16\x26\xa1\x8c\x8b\x9d\x1f\x0c\x0c\x20\xab\x99\x9e\xbb\x5d\xbe\xa7\xac\x32\x13\x0d\x1a\xab\x8c\x89\x97\x2e\x10\x10\x21\xc3\xab\xbc\x4f\xd4\xa2\x96\x9c\x3f\x10\x0a\x12\xc4\x8f\x8a\x95\x57\x1b\x1a\x2b\xfd\x5d\x2d\x27\x62\x9b\x8e\x92\xc9\x12\x09\x0e\x3f\x97\x8e\x98\xc6\x2c\x2f\x6b\xd9\x2e\x1a\x18\x34\x9a\x8b\x8d\xab\x18\x0a\x0e\x2d\xa1\x98\xa1\xc7\x5b\xb9\xa7\xb4\x27\x10\x0e\x22\x9d\x8a\x8b\x9f\x20\x0e\x12\x2a\xb4\xaa\xc0\x50\xc0\x9e\x97\xa1\x2a\x0e\x0a\x19\xa8\x8c\x8b\x9b\x31\x18\x1b\x31")); -snd($sock_b, $port_a, rtp(0, 4009, 9440, 0x6543, "\x00" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4009, 9440, $ssrc, "\xda\x50\x2c\x2b\xc0\x97\x8e\x97\x39\x0e\x09\x13\xbf\x92\x8e\x9c\x57\x29\x31\xef\x72\x28\x19\x1b\x6d\x94\x8a\x8f\xce\x11\x0a\x11\x48\x9c\x98\xa5\xdc\x5e\xb5\xa9\xc6\x1f\x0f\x10\x31\x96\x89\x8d\xad\x19\x0e\x15\x37\xac\xaa\xc8\x57\xb7\x9c\x98\xac\x1e\x0c\x0c\x21\x9c\x8b\x8d\xa4\x25\x17\x1d\x3b\xcf\x48\x2b\x30\xae\x93\x8e" . "\xff" x 80)); -# pause -snd($sock_b, $port_a, rtp(0, 4010, 9600, 0x6543, "\x00" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4010, 9600, $ssrc, "\xff" x 160)); -snd($sock_b, $port_a, rtp(0, 4011, 9760, 0x6543, "\x00" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4011, 9760, $ssrc, "\xff" x 160)); -snd($sock_b, $port_a, rtp(0, 4012, 9920, 0x6543, "\x00" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4012, 9920, $ssrc, "\xff" x 160)); -snd($sock_b, $port_a, rtp(0, 4013, 10080, 0x6543, "\x00" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4013, 10080, $ssrc, "\xff" x 160)); -snd($sock_b, $port_a, rtp(0, 4014, 10240, 0x6543, "\x00" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4014, 10240, $ssrc, "\xff" x 80 . "\x00" x 80)); - - - - -# transcoding, no RFC payload type present - -($sock_a, $sock_b) = new_call([qw(198.51.100.1 6018)], [qw(198.51.100.3 6020)]); - -($port_a) = offer('transcoding, no RFC payload type present', - { ICE => 'remove', replace => ['origin'], flags => ['inject DTMF'], - codec => { transcode => ['PCMA'] } }, < 'remove', replace => ['origin'], flags => ['inject DTMF'] }, < ft(), code => 'C', volume => 5, duration => 120 }); - -snd($sock_a, $port_b, rtp(0, 1002, 3320, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(8, 1002, 3320, $ssrc, "\xd5\xb9\xbe\x97\x05\x70\xea\x01\x3e\x31\x82\xa5\xb2\x63\x0f\x69\xc1\x0f\x3d\x06\xb3\xa4\x8a\x03\x35\x14\x75\x0e\x36\xcc\xb8\xa5\x9d\x36\x36\x68\x49\x0d\x0c\x81\xa5\xbf\x16\x3f\x37\x4f\xcf\x07\x13\xb4\xa5\xb4\x0a\x3b\x0b\xeb\xe9\x12\xc9\xb3\xb8\x92\x3c\x3a\x07\x87\x9c\x61\x93\xb2\xb3\x12\x25\x39\x76\x8b\x85\x5a\x85\xb3\x8e\x35\x24\x30\x85\xb1\x87\x57\x84\xb7\xeb\x3c\x24\x0d\xb4\xb2\x9b\x70\x98\x8c\x11\x3b\x38\x41\xbf\xb2\xeb\x15\x96\x9f\x0d\x3a\x30\x83\xba\xb1\x7b\x1b\xfa\xf2\x34\x39\x03\xb0\xa5\x88\x04\x03\x5f\x67\x37\x32\xdd\xb8\xba\x9d\x35\x0e\x71\x15\x37\x0a\x80\xa4\xbf\x15\x33\x09\x45\x15\x0b\x18\xb6\xa4\xb4\x08\x3f\x0d\xe5\x66")); -snd($sock_a, $port_b, rtp(0, 1003, 3480, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(8, 1003, 3480, $ssrc, "\x00\xcd\xbc\xba\x9c\x3d\x39\x1a\x9d\xd1\x1d\x98\xbe\xbd\x10\x3a\x3f\x73\x80\xe0\x64\x82\xbf\x8b\x35\x24\x31\x9f\x8b\x94\xdf\x8e\xb3\x96\x3c\x24\x02\x8b\xb7\x94\xf4\x8f\xb5\x10\x3a\x3b\x76\xb2\xb6\xe0\xd6\x80\x87\x09\x25\x33\x81\xb9\xb4\x74\x64\x9b\xe6\x31\x3a\x0d\xb1\xba\x8f\x1c\x11\x95\x6f\x32\x3f\x5e\xb8\xbb\x92\x0d\x1a\xf0\x19\x32\x37\x83\xa4\xbc\x6d\x37\x07\xd4\x04\x31\x07\xb1\xa4\xb4\x0c\x33\x04\xc5\x05\x0b\xd8\xbe\xa5\x9e\x30\x3d\x1d\xe0\x1d\x06\x84\xbb\xbf\x16\x38\x33\x73\x92\x6f\x15\x88\xbb\xb5\x35\x25\x37\x91\x86\x46\xda\xb7\xbf\x92\x3c\x25\x03\x8d\x8c\xf4\xef\xb7\xb6\x10\x25\x3b\x7f\xb6\x89\xf6\x95\xb5\x82\x0b\x24\x33\x84")); -snd($sock_a, $port_b, rtp(0, 1004, 3640, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(8, 1004, 3640, $ssrc, "\xbd\x8e\x5a\xec\x8c\xee\x33\x24\x0c\xb6\xbe\x80\x6b\xf5\x85\x6a\x3f\x39\x4a\xbe\xbe\x90\x05\x7f\x95\x06\x3e\x31\x80\xa5\xbd\x64\x0f\x6b\xcc\x0c\x3d\x00\xb0\xa4\xb5\x00\x34\x16\x4e\x0e\x36\x57\xb9\xa5\x99\x36\x36\x6a\x43\x0d\x0f\x86\xa5\xbe\x15\x3f\x36\x77\xf5\x07\x12\xb4\xa5\xb4\x0b\x3b\x0a\xee\xeb\x13\xd8\xb0\xb8\x9f\x3c\x3a\x01\x87\x9f\x66\x91\xb2\xb3\x11\x25\x39\x7a\x8b\x84\x5b\x9a\xb0\x89\x0a\x24\x33\x9b\xb1\x87\x54\x85\xb7\x97\x3d\x24\x0c\xb4\xb2\x9a\x73\x99\x8c\x14\x38\x3b\x7c\xbc\xbd\x94\x15\x97\x9e\x02\x3a\x33\x81\xba\xb0\x73\x1a\xfe\xf9\x35\x39\x02\xb1\xa4\x8a\x05\x03\x44\x7a\x37\x32\x40\xb8\xa5\x99\x0a\x0e\x72\x6b\x34\x35")); -snd($sock_a, $port_b, rtp(0, 1005, 3800, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(8, 1005, 3800, $ssrc, "\x81\xa4\xbe\x6c\x33\x08\x43\x68\x08\x1a\xb7\xa4\xb7\x0e\x3f\x0c\xfb\x65\x00\xd1\xbd\xba\x98\x32\x39\x04\x92\xdb\x1d\x9e\xbe\xbc\x17\x3a\x3f\x65\x80\xed\x67\x83\xbf\xb5\x0a\x24\x30\x9d\x8b\x97\xd0\x8f\xb3\x93\x3c\x24\x0c\x88\xb7\x96\xc9\x8c\xb5\x17\x3a\x3a\x64\xb3\xb6\xed\x56\x80\x86\x0f\x25\x32\x87\xb9\xb7\x4d\x66\x98\xe3\x36\x3a\x0c\xb1\xba\x8e\x1d\x10\xea\x63\x33\x3f\x70\xb9\xbb\x9f\x0d\x05\xf1\x1f\x33\x36\x81\xa4\xbf\x67\x34\x06\xd5\x05\x31\x06\xb6\xa4\xb7\x0d\x33\x07\xc5\x1a\x0a\x5f\xbe\xa5\x9a\x30\x3d\x1f\xe0\x12\x06\x9a\xbb\xbf\x6b\x39\x32\x7b\x9d\x62\x14\x89\xbb\xb4\x0b\x25\x36\x97\x86\x5e\xd1\xb4\xbf\x9e\x3c\x24\x0d\x82\x8c")); -snd($sock_a, $port_b, rtp(0, 1006, 3960, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(8, 1006, 3960, $ssrc, "\xf0\xe2\xb7\xb1\x14\x3a\x3b\x61\xb6\x88\xf3\xeb\xb5\x8d\x09\x24\x32\x85\xbd\x89\x5c\xe2\x8c\x95\x30\x24\x0e\xb7\xb9\x83\x68\xc3\x85\x6e\x3f\x38\x7a\xbe\xb9\x92\x05\x7a\x95\x07\x3e\x30\x86\xa5\xbd\x7c\x0f\x15\xcb\x0d\x3d\x03\xb1\xa4\xb4\x01\x34\x11\x40\x0f\x36\x48\xb9\xa5\x85\x37\x36\x14\x45\x02\x0f\x84\xa5\xbe\x6d\x3c\x36\x7d\xf1\x04\x1c\xb5\xa5\xb7\x09\x3b\x35\xed\xea\x13\x57\xb0\xb8\x9b\x3d\x3a\x00\x84\x9e\x66\x97\xb2\xb2\x15\x3a\x38\x60\x8b\x87\x58\x98\xb0\x88\x08\x24\x32\x9e\xb1\x86\x54\x9a\xb7\x90\x32\x24\x0e\xb5\xb2\x84\x73\x9f\x8c\x68\x38\x3b\x61\xbc\xbd\x96\x14\x94\x99\x03\x3b\x32\x87\xba\xb3\x48\x1a\xf2\xe5\x0a\x39\x0c\xb1")); -snd($sock_a, $port_b, rtp(0, 1007, 4120, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(8, 1007, 4120, $ssrc, "\xa4\xb5\x1a\x02\x4c\x7f\x37\x32\x7c\xb9\xa5\x9a\x0a\x09\x7e\x6e\x34\x35\x87\xa5\xbe\x67\x33\x0b\x48\x6e\x08\x05\xb7\xa4\xb6\x0f\x3f\x0e\xfe\x79\x00\x5a\xbd\xa5\x85\x32\x39\x07\x92\xcd\x1d\x9d\xbe\xbc\x69\x3b\x3e\x60\x80\xef\x66\x80\xbf\xb5\x08\x24\x30\x90\x8b\x91\xd5\x8c\xb3\x9f\x3d\x24\x0e\x89\xb7\x91\xc2\x8c\xb5\x68\x3b\x3a\x6d\xb3\xb1\xee\x5c\x81\x81\x0c\x25\x3d\x85\xb9\xb7\x58\x60\x99\xef\x37\x3a\x0e\xb6\xba\x89\x12\x13\xeb\x67\x33\x3e\x67\xb9\xba\x98\x02\x05\xf7\x1d\x33\x36\x87\xa4\xbe\x7c\x34\x01\x54\x1a\x31\x01\xb6\xa4\xb6\x03\x33\x06\xda\x18\x0a\x75\xbf\xa5\x84\x31\x3d\x19\xe0\x10\x01\x99\xbb\xbe\x62\x39\x3d\x66\x9d\x60\x17")); -# pause -snd($sock_a, $port_b, rtp(0, 1008, 4280, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(8, 1008, 4280, $ssrc, "\xd5" x 160)); -snd($sock_a, $port_b, rtp(0, 1009, 4440, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(8, 1009, 4440, $ssrc, "\xd5" x 160)); -snd($sock_a, $port_b, rtp(0, 1010, 4600, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(8, 1010, 4600, $ssrc, "\xd5" x 160)); -snd($sock_a, $port_b, rtp(0, 1011, 4760, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(8, 1011, 4760, $ssrc, "\xd5" x 160)); -snd($sock_a, $port_b, rtp(0, 1012, 4920, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(8, 1012, 4920, $ssrc, "\xd5" x 160)); -snd($sock_a, $port_b, rtp(0, 1013, 5080, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(8, 1013, 5080, $ssrc, "\x2a" x 160)); - - - - -snd($sock_b, $port_a, rtp(8, 4000, 8000, 0x6543, "\x2a" x 160)); -($ssrc) = rcv($sock_a, $port_b, rtpm(0, 4000, 8000, -1, "\x00" x 160)); -snd($sock_b, $port_a, rtp(8, 4001, 8160, 0x6543, "\x2a" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4001, 8160, $ssrc, "\x00" x 160)); - -$resp = rtpe_req('play DTMF', 'inject DTMF towards A', - { 'from-tag' => tt(), code => '4', volume => 3, duration => 150 }); - -snd($sock_b, $port_a, rtp(8, 4002, 8320, 0x6543, "\x2a" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4002, 8320, $ssrc, "\xff\x90\x8a\x93\xd9\x1b\x18\x27\x65\xe5\x33\x29\x4c\x9e\x8f\x91\xb8\x15\x09\x0d\x32\x98\x8e\x96\xbb\x2c\x2b\x4c\xd8\x34\x1c\x18\x2e\x9d\x8c\x8c\xa5\x1a\x0b\x0d\x27\xa3\x97\x9e\xbd\x4f\xc4\xaa\xb2\x2c\x12\x0e\x1e\xa1\x8b\x8a\x9c\x25\x0e\x10\x25\xb7\xa7\xb7\x5e\xcb\xa2\x98\x9f\x30\x0f\x0a\x16\xae\x8d\x8a\x98\x3a\x18\x19\x2c\xdd\xfd\x30\x2b\xce\x99\x8e\x95\x4c\x0f\x09\x10\xdf\x93\x8e\x9a\xec\x28\x2c\x56\xee\x2d\x1a\x1a\x48\x97\x8b\x8e\xba\x14\x0a\x0f\x39\x9d\x96\xa1\xcd\x4e\xbe\xab\xbe\x23\x10\x10\x2b\x99\x8a\x8c\xa7\x1b\x0d\x12\x2f\xad\xa7\xbc\x5e\xbd\x9f\x99\xa8\x23\x0d\x0b\x1d\x9f\x8b\x8c\x9f\x29\x16\x1b\x34\xcd\x60\x2f\x2f\xb6\x96")); -snd($sock_b, $port_a, rtp(8, 4003, 8480, 0x6543, "\x2a" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4003, 8480, $ssrc, "\x8e\x9b\x2b\x0c\x09\x17\xae\x8f\x8e\x9e\x3f\x25\x2e\x65\x5c\x28\x1a\x1e\xc2\x92\x8a\x92\x44\x0f\x0a\x14\xd6\x99\x97\xa6\x7c\x4e\xba\xad\xe5\x1d\x0f\x13\x49\x92\x89\x8e\xbe\x15\x0d\x16\x43\xa8\xa7\xc1\x66\xb5\x9d\x9a\xb6\x1b\x0c\x0d\x2b\x98\x8a\x8d\xab\x1f\x15\x1d\x3f\xc7\x52\x2e\x39\xaa\x93\x8f\xa3\x1e\x0b\x0b\x1e\x9f\x8d\x8f\xa7\x30\x23\x31\x7c\x4a\x24\x1a\x24\xac\x8e\x8b\x99\x28\x0c\x0a\x1a\xb0\x96\x98\xac\x4f\x53\xb7\xaf\x44\x19\x0f\x18\xba\x8e\x89\x93\x3f\x10\x0d\x1a\xd5\xa3\xa8\xca\xf9\xae\x9c\x9d\xec\x16\x0b\x10\x4e\x91\x89\x90\xc6\x1a\x14\x20\x55\xc3\x4a\x2f\x49\xa2\x91\x92\xb2\x17\x09\x0c\x2d\x99\x8d\x92\xb3\x29\x23\x36\xf2")); -snd($sock_b, $port_a, rtp(8, 4004, 8640, 0x6543, "\x2a" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4004, 8640, $ssrc, "\x3e\x20\x1b\x2d\xa0\x8d\x8c\xa1\x1c\x0a\x0c\x22\xa3\x94\x9a\xb5\x44\x5c\xb5\xb6\x32\x16\x0f\x1e\xa6\x8c\x8a\x99\x28\x0e\x0e\x20\xb7\xa1\xab\xd4\xdb\xaa\x9c\xa1\x38\x11\x0b\x15\xb5\x8d\x8a\x96\x3f\x16\x15\x26\xdd\xc2\x43\x31\xdf\x9d\x90\x96\x6d\x11\x09\x0f\x5a\x93\x8c\x97\xd2\x23\x23\x3b\xf6\x37\x1f\x1d\x40\x9a\x8c\x8e\xb2\x15\x09\x0e\x31\x9c\x93\x9c\xc2\x3e\x74\xb4\xbf\x29\x14\x11\x29\x9b\x8a\x8b\xa3\x1c\x0d\x0f\x2a\xab\x9f\xad\xe0\xcc\xa6\x9c\xa9\x28\x0e\x0c\x1c\xa2\x8b\x8b\x9c\x2a\x14\x17\x2c\xc6\xc4\x3e\x36\xbd\x99\x90\x9b\x30\x0d\x09\x15\xb3\x8f\x8d\x9b\x42\x1f\x25\x42\x70\x30\x1e\x1f\xcf\x95\x8b\x92\x58\x0f\x09\x12\x6f\x98\x93")); -snd($sock_b, $port_a, rtp(8, 4005, 8800, 0x6543, "\x2a" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4005, 8800, $ssrc, "\x9f\xe5\x3b\xe2\xb5\xd9\x21\x12\x14\x3e\x95\x89\x8d\xb6\x16\x0c\x13\x3a\xa4\x9f\xb1\xf1\xc0\xa3\x9d\xb4\x1e\x0d\x0d\x27\x99\x8a\x8c\xa7\x1f\x12\x19\x37\xbc\xc8\x3c\x3c\xaf\x97\x91\xa2\x21\x0b\x0a\x1c\xa2\x8d\x8e\xa2\x2f\x1e\x28\x4c\x5d\x2c\x1e\x25\xb0\x90\x8c\x98\x2c\x0c\x0a\x18\xb4\x94\x94\xa6\x4d\x3a\xd4\xb8\x4f\x1d\x11\x18\xc5\x8f\x89\x91\x4d\x10\x0c\x17\xec\x9f\xa0\xb8\xff\xba\xa1\x9f\xd3\x19\x0c\x0f\x3f\x92\x89\x8f\xbb\x19\x11\x1c\x48\xb8\xce\x3b\x4a\xa8\x95\x93\xaf\x19\x0a\x0c\x29\x99\x8c\x8f\xad\x27\x1d\x2b\x59\x4f\x29\x1e\x2d\xa5\x8e\x8d\x9f\x1e\x0b\x0b\x1e\xa4\x91\x96\xad\x3e\x3b\xcc\xbc\x3a\x1a\x12\x1e\xaa\x8d\x8a\x98\x2b")); -snd($sock_b, $port_a, rtp(8, 4006, 8960, 0x6543, "\x2a" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4006, 8960, $ssrc, "\x0e\x0c\x1d\xb8\x9d\xa2\xbe\xf9\xb4\xa0\xa3\x3f\x14\x0c\x14\xbd\x8e\x89\x93\x49\x15\x12\x1f\xe7\xb5\xd9\x3c\x7c\xa1\x93\x97\xd5\x13\x09\x0e\x45\x93\x8b\x93\xc4\x20\x1d\x2e\x6b\x46\x26\x1f\x3d\x9d\x8d\x8e\xae\x17\x09\x0d\x2c\x9c\x90\x98\xba\x36\x3d\xc7\xc4\x2e\x17\x13\x27\x9e\x8b\x8b\x9f\x1e\x0c\x0e\x25\xaa\x9c\xa5\xc8\xe8\xae\xa0\xaa\x2d\x10\x0c\x1b\xa6\x8c\x8a\x9a\x2c\x12\x13\x27\xc3\xb3\xed\x3e\xc8\x9d\x93\x9b\x38\x0f\x09\x13\xba\x8f\x8b\x98\x4a\x1d\x1e\x34\xf9\x3e\x24\x23\xea\x98\x8c\x92\xdf\x10\x09\x0f\x4d\x97\x90\x9c\xd2\x31\x3f\xc5\xd6\x28\x16\x16\x39\x97\x8a\x8d\xaf\x17\x0b\x10\x32\xa2\x9b\xa8\xd6\xd9\xac\xa1\xb3\x22\x0e\x0e")); -snd($sock_b, $port_a, rtp(8, 4007, 9120, 0x6543, "\x2a" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4007, 9120, $ssrc, "\x24\x9b\x8a\x8b\xa2\x1f\x10\x15\x2f\xb8\xb4\x68\x43\xb8\x9a\x94\xa1\x25\x0c\x0a\x1a\xa5\x8d\x8c\x9e\x30\x1b\x1f\x3c\xee\x38\x23\x28\xb8\x93\x8d\x97\x31\x0d\x09\x15\xb9\x93\x90\xa0\x4f\x2f\x46\xc4\x5e\x21\x15\x19\xd7\x91\x89\x90\x7b\x10\x0b\x14\x5b\x9d\x9c\xad\xed\xcd\xa9\xa3\xca\x1c\x0d\x10\x38\x94\x89\x8e\xb3\x19\x0f\x18\x3e\xb0\xb5\x59\x4d\xae\x98\x95\xad\x1c\x0b\x0c\x25\x9b\x8b\x8e\xa9\x26\x1a\x22\x46\xf5\x33\x23\x2e\xaa\x90\x8d\x9e\x21\x0b\x0a\x1c\xa6\x90\x92\xa8\x3b\x2e\x4d\xc7\x43\x1e\x15\x1e\xaf\x8e\x8a\x96\x2e\x0e\x0b\x1a\xbb\x9b\x9d\xb2\x68\xc5\xa8\xa7\x4c\x17\x0d\x14\xcb\x8f\x89\x91\x5e\x14\x0f\x1c\x6e\xad\xb8\x52\x68\xa8")); -snd($sock_b, $port_a, rtp(8, 4008, 9280, 0x6543, "\x2a" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4008, 9280, $ssrc, "\x97\x98\xc7\x16\x0a\x0e\x3a\x94\x8a\x90\xbb\x1e\x1a\x27\x56\x6f\x2f\x25\x3b\xa0\x8e\x8f\xaa\x19\x09\x0c\x28\x9c\x8f\x95\xb2\x31\x2e\x59\xcc\x37\x1b\x16\x26\xa1\x8c\x8b\x9d\x1f\x0c\x0c\x20\xab\x99\x9e\xbb\x5d\xbe\xa7\xac\x32\x13\x0d\x1a\xab\x8c\x89\x97\x2e\x10\x10\x21\xc3\xab\xbc\x4f\xd4\xa2\x96\x9c\x3f\x10\x0a\x12\xc4\x8f\x8a\x95\x57\x1b\x1a\x2b\xfd\x5d\x2d\x27\x62\x9b\x8e\x92\xc9\x12\x09\x0e\x3f\x97\x8e\x98\xc6\x2c\x2f\x6b\xd9\x2e\x1a\x18\x34\x9a\x8b\x8d\xab\x18\x0a\x0e\x2d\xa1\x98\xa1\xc7\x5b\xb9\xa7\xb4\x27\x10\x0e\x22\x9d\x8a\x8b\x9f\x20\x0e\x12\x2a\xb4\xaa\xc0\x50\xc0\x9e\x97\xa1\x2a\x0e\x0a\x19\xa8\x8c\x8b\x9b\x31\x18\x1b\x31")); -snd($sock_b, $port_a, rtp(8, 4009, 9440, 0x6543, "\x2a" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4009, 9440, $ssrc, "\xda\x50\x2c\x2b\xc0\x97\x8e\x97\x39\x0e\x09\x13\xbf\x92\x8e\x9c\x57\x29\x31\xef\x72\x28\x19\x1b\x6d\x94\x8a\x8f\xce\x11\x0a\x11\x48\x9c\x98\xa5\xdc\x5e\xb5\xa9\xc6\x1f\x0f\x10\x31\x96\x89\x8d\xad\x19\x0e\x15\x37\xac\xaa\xc8\x57\xb7\x9c\x98\xac\x1e\x0c\x0c\x21\x9c\x8b\x8d\xa4\x25\x17\x1d\x3b\xcf\x48\x2b\x30\xae\x93\x8e" . "\xff" x 80)); -# pause -snd($sock_b, $port_a, rtp(0, 4010, 9600, 0x6543, "\x00" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4010, 9600, $ssrc, "\xff" x 160)); -snd($sock_b, $port_a, rtp(0, 4011, 9760, 0x6543, "\x00" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4011, 9760, $ssrc, "\xff" x 160)); -snd($sock_b, $port_a, rtp(0, 4012, 9920, 0x6543, "\x00" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4012, 9920, $ssrc, "\xff" x 160)); -snd($sock_b, $port_a, rtp(0, 4013, 10080, 0x6543, "\x00" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4013, 10080, $ssrc, "\xff" x 160)); -snd($sock_b, $port_a, rtp(0, 4014, 10240, 0x6543, "\x00" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4014, 10240, $ssrc, "\xff" x 80 . "\x00" x 80)); - - - - -# multiple consecutive DTMF events - -($sock_a, $sock_b) = new_call([qw(198.51.100.1 6024)], [qw(198.51.100.3 6026)]); - -($port_a) = offer('multiple consecutive DTMF events', - { ICE => 'remove', replace => ['origin'], flags => ['inject DTMF'] }, < 'remove', replace => ['origin'], flags => ['inject DTMF'] }, < ft(), code => 'C', volume => 5, duration => 100 }); -$resp = rtpe_req('play DTMF', 'inject DTMF towards B', - { 'from-tag' => ft(), code => '4', volume => 5, duration => 100 }); - -snd($sock_a, $port_b, rtp(0, 1002, 3320, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1002, 3320, $ssrc, "\xff\x93\x94\xbc\x2e\x56\xbf\x2b\x13\x1b\xa7\x8e\x98\x47\x25\x41\xe2\x24\x16\x2b\x99\x8e\x9f\x28\x1e\x3d\x5b\x23\x1c\xdf\x92\x8f\xb6\x1c\x1c\x40\x5d\x26\x25\xaa\x8f\x95\x3b\x15\x1d\x5e\xde\x2c\x38\x9d\x8f\x9e\x1f\x11\x20\xc0\xc1\x37\xdd\x99\x92\xb7\x15\x10\x2c\xac\xb5\x49\xb8\x97\x99\x37\x0f\x13\x58\xa0\xae\x67\xae\x99\xa4\x1f\x0d\x1a\xae\x9b\xad\x7b\xad\x9d\xbf\x16\x0e\x27\x9d\x98\xb0\x55\xb1\xa6\x3a\x11\x11\x63\x95\x98\xbf\x3e\xbb\xb4\x26\x10\x1a\xa9\x90\x9a\x4e\x30\xce\xd4\x1e\x12\x29\x99\x8e\xa1\x2d\x29\x6d\x4b\x1c\x18\xef\x91\x8f\xb6\x1f\x24\x57\x3e\x1d\x20\xa9\x8e\x95\x3e\x19\x23\x67\x3e\x21\x31\x9c\x8e\x9e\x22\x14\x26\xcd\x4a")); -snd($sock_a, $port_b, rtp(0, 1003, 3480, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1003, 3480, $ssrc, "\x2a\xdf\x96\x90\xb5\x17\x13\x2f\xb6\xf5\x36\xb1\x93\x96\x39\x10\x15\x55\xaa\xc8\x4c\xa7\x95\xa0\x1f\x0e\x1b\xb4\xa1\xbd\xed\xa4\x99\xbb\x15\x0e\x27\xa0\x9d\xbd\xda\xa4\x9f\x39\x10\x11\x58\x98\x9c\xc8\xf9\xa9\xac\x23\x0e\x19\xab\x92\x9e\x59\x4c\xb0\xca\x1b\x10\x27\x9a\x90\xa5\x35\x3a\xbe\x43\x18\x15\x6c\x92\x91\xb7\x26\x30\xd6\x32\x18\x1d\xa9\x8e\x96\x44\x1d\x2d\xfc\x2e\x1b\x2d\x9a\x8d\x9e\x25\x19\x2d\xe7\x2f\x20\xea\x94\x8f\xb3\x19\x17\x36\xc8\x36\x2c\xae\x90\x95\x3b\x12\x18\x55\xb7\x43\x3e\xa1\x91\x9e\x1f\x0f\x1d\xba\xac\x64\xe8\x9d\x95\xb7\x15\x0e\x29\xa6\xa6\xda\xc3\x9d\x9b\x39\x0f\x11\x51\x9c\xa2\xd8\xbe\x9f\xa7\x21\x0e\x18\xad")); -snd($sock_a, $port_b, rtp(0, 1004, 3640, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1004, 3640, $ssrc, "\x96\xa3\x68\xc4\xa5\xc2\x19\x0e\x26\x9c\x93\xa9\x3f\xdb\xae\x3e\x14\x12\x5b\x93\x93\xb9\x2e\x51\xbe\x2c\x14\x1b\xa9\x8f\x97\x4c\x25\x3f\xde\x25\x16\x2a\x9a\x8e\x9e\x29\x1e\x3b\x5e\x24\x1b\x7b\x92\x8f\xb2\x1c\x1c\x3e\x61\x27\x25\xac\x8f\x94\x3e\x15\x1c\x59\xdb\x2d\x37\x9e\x8f\x9d\x20\x11\x1f\xc2\xbf\x38\xea\x99\x92\xb4\x16\x10\x2b\xad\xb4\x49\xba\x98\x98\x3a\x0f\x12\x4e\xa1\xad\x68\xaf\x99\xa3\x20\x0d\x19\xb0\x9b\xac\x7b\xae\x9d\xbc\x17\x0e\x25\x9e\x98\xaf\x55\xb2\xa6\x3d\x12\x11\x52\x96\x97\xbd\x3e\xbc\xb3\x28\x10\x19\xab\x90\x9a\x54\x2f\xd0\xcf\x1f\x12\x27\x9a\x8e\xa0\x2e\x28\x66\x4e\x1d\x18\x62\x92\x8f\xb2\x20\x23\x53\x3f\x1d\x1f")); -snd($sock_a, $port_b, rtp(0, 1005, 3800, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1005, 3800, $ssrc, "\xab\x8e\x94\x44\x19\x22\x61\x40\x21\x2f\x9c\x8e\x9d\x23\x14\x25\xce\x4d\x2a\xf7\x96\x8f\xb1\x18\x13\x2e\xb7\xe8\x36\xb3\x94\x96\x3c\x10\x15\x4d\xaa\xc5\x4b\xa8\x95\x9f\x20\x0e\x1a\xb6\xa0\xbc\xf5\xa4\x99\xb8\x16\x0e\x26\xa1\x9d\xbb\xdd\xa5\x9f\x3c\x10\x10\x4c\x99\x9b\xc5\x78\xaa\xac\x24\x0f\x18\xac\x93\x9d\x5f\x4a\xb1\xc7\x1c\x0f\x25\x9b\x90\xa3\x36\x39\xbf\x47\x18\x14\x56\x92\x90\xb4\x27\x2f\xd7\x34\x18\x1c\xab\x8e\x95\x4b\x1d\x2c\xfe\x2f\x1b\x2c\x9b\x8d\x9d\x27\x19\x2c\xe7\x30\x20\x6d\x94\x8f\xaf\x1a\x17\x34\xc8\x37\x2b\xaf\x91\x94\x3f\x12\x18\x4e\xb6\x45\x3d\xa3\x91\x9e\x20\x0f\x1c\xbc\xab\x6c\xf5\x9e\x95\xb3\x16\x0e\x27\xa7\xa5")); -snd($sock_a, $port_b, rtp(0, 1006, 3960, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1006, 3960, $ssrc, "\xd6\xc6\x9d\x9b\x3d\x0f\x11\x49\x9c\xa1\xd4\xbf\x9f\xa6\x22\x0e\x18\xaf\x96\xa2\x6e\xc6\xa5\xbe\x19\x0e\x24\x9d\x93\xa8\x40\xe1\xae\x42\x15\x12\x4e\x94\x93\xb7\x2e\x4e\xbe\x2d\x14\x1a\xab\x8f\x97\x52\x25\x3e\xdc\x26\x16\x28\x9b\x8e\x9e\x2b\x1e\x3a\x61\x25\x1b\x5d\x93\x8f\xaf\x1d\x1c\x3d\x67\x27\x24\xad\x8f\x93\x45\x15\x1c\x53\xd7\x2d\x35\x9f\x8f\x9c\x22\x11\x1f\xc5\xbe\x38\x7a\x9a\x91\xb0\x17\x10\x29\xad\xb3\x4a\xbc\x98\x98\x3e\x10\x12\x48\xa1\xad\x6a\xb1\x9a\xa1\x21\x0e\x18\xb3\x9b\xab\x7d\xaf\x9d\xb9\x18\x0e\x23\x9f\x97\xae\x55\xb4\xa5\x40\x12\x10\x49\x96\x97\xbb\x3d\xbd\xb2\x29\x10\x18\xac\x90\x99\x5d\x2f\xd4\xcd\x1f\x12\x25\x9b")); -# pause -snd($sock_a, $port_b, rtp(0, 1007, 4120, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1007, 4120, $ssrc, "\xff" x 160)); -snd($sock_a, $port_b, rtp(0, 1008, 4280, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1008, 4280, $ssrc, "\xff" x 160)); -snd($sock_a, $port_b, rtp(0, 1009, 4440, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1009, 4440, $ssrc, "\xff" x 160)); -snd($sock_a, $port_b, rtp(0, 1010, 4600, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1010, 4600, $ssrc, "\xff" x 160)); -snd($sock_a, $port_b, rtp(0, 1011, 4760, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1011, 4760, $ssrc, "\xff" x 160)); -# next event -snd($sock_a, $port_b, rtp(0, 1012, 4920, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1012, 4920, $ssrc, "\xff\x96\x8e\x99\xdd\x1f\x1d\x2c\x69\xe9\x39\x2d\x50\xa3\x95\x97\xbd\x1a\x0e\x12\x38\x9d\x93\x9b\xbf\x30\x2f\x4f\xdc\x39\x20\x1d\x33\xa2\x90\x91\xaa\x1f\x0f\x12\x2c\xa9\x9c\xa3\xc2\x55\xc9\xaf\xb8\x30\x18\x14\x24\xa7\x8f\x8e\xa0\x2a\x14\x16\x2a\xbc\xac\xbc\x61\xcf\xa8\x9d\xa6\x36\x15\x0f\x1b\xb4\x92\x8f\x9d\x3e\x1d\x1e\x31\xe0\xfe\x36\x30\xd3\x9e\x94\x9b\x50\x15\x0d\x17\xe3\x99\x93\x9e\xee\x2c\x30\x5b\xf0\x32\x1f\x1f\x4c\x9c\x8f\x94\xbe\x19\x0e\x15\x3d\xa2\x9b\xa7\xd2\x52\xc3\xaf\xc4\x29\x16\x16\x2f\x9e\x8e\x90\xac\x20\x13\x18\x34\xb2\xac\xc0\x61\xc2\xa5\x9d\xad\x29\x12\x10\x23\xa5\x8f\x90\xa5\x2d\x1b\x1f\x39\xd1\x65\x34\x36\xbb\x9b")); -snd($sock_a, $port_b, rtp(0, 1013, 5080, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1013, 5080, $ssrc, "\x94\x9f\x2f\x11\x0e\x1c\xb3\x95\x94\xa4\x45\x2a\x33\x69\x60\x2d\x1e\x23\xc7\x98\x8f\x98\x49\x15\x0e\x1a\xda\x9d\x9c\xab\x7d\x53\xbe\xb1\xe8\x22\x15\x19\x4d\x98\x8d\x94\xc3\x1b\x12\x1b\x48\xac\xac\xc7\x69\xba\xa2\x9f\xbb\x1f\x10\x12\x2f\x9c\x8e\x93\xb0\x25\x1a\x22\x44\xcb\x57\x34\x3d\xae\x99\x96\xa9\x23\x0f\x0f\x24\xa6\x93\x96\xac\x36\x29\x37\x7c\x4e\x29\x1e\x29\xb0\x94\x8f\x9e\x2d\x11\x0f\x1f\xb6\x9b\x9d\xb0\x55\x58\xbc\xb5\x49\x1e\x15\x1d\xbe\x94\x8e\x99\x45\x17\x12\x1f\xd9\xa9\xad\xce\xfa\xb3\xa0\xa2\xef\x1b\x0f\x16\x52\x97\x8e\x96\xcb\x1e\x1a\x26\x59\xc8\x4e\x35\x4d\xa8\x97\x98\xb8\x1c\x0e\x11\x31\x9d\x91\x98\xb9\x2d\x29\x3b\xf5")); -snd($sock_a, $port_b, rtp(0, 1014, 5240, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1014, 5240, $ssrc, "\x43\x27\x1f\x32\xa6\x92\x91\xa7\x21\x0f\x10\x28\xa9\x99\x9e\xba\x49\x60\xba\xbb\x38\x1b\x16\x23\xab\x90\x8e\x9e\x2d\x14\x13\x26\xbc\xa7\xaf\xd8\xde\xae\xa0\xa7\x3d\x17\x0f\x1a\xba\x93\x8e\x9b\x44\x1b\x1b\x2b\xe0\xc8\x48\x37\xe4\xa2\x96\x9b\x6f\x17\x0e\x15\x5d\x99\x91\x9c\xd7\x29\x29\x3f\xf8\x3c\x24\x21\x46\x9e\x90\x94\xb8\x1a\x0e\x14\x37\xa1\x99\xa1\xc8\x43\x76\xba\xc5\x2d\x19\x17\x2d\xa0\x8f\x8f\xa8\x21\x11\x16\x2e\xaf\xa6\xb2\xe5\xcf\xab\xa0\xad\x2d\x14\x10\x20\xa8\x90\x8f\xa1\x2e\x19\x1c\x31\xcb\xc9\x44\x3b\xc2\x9e\x96\x9f\x36\x13\x0e\x1a\xb8\x95\x92\xa0\x48\x26\x2a\x48\x73\x36\x23\x25\xd4\x9a\x90\x98\x5c\x15\x0e\x18\x72\x9c\x99")); -snd($sock_a, $port_b, rtp(0, 1015, 5400, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1015, 5400, $ssrc, "\xa6\xe8\x3f\xe7\xba\xdd\x27\x18\x1a\x43\x9a\x8e\x93\xbb\x1b\x10\x19\x3e\xaa\xa5\xb7\xf4\xc6\xa9\xa2\xba\x23\x12\x12\x2c\x9e\x8e\x91\xac\x25\x18\x1e\x3c\xc1\xcd\x41\x40\xb5\x9c\x97\xa8\x27\x10\x0f\x21\xa8\x92\x93\xa8\x35\x24\x2c\x50\x61\x30\x23\x2b\xb7\x97\x90\x9d\x31\x11\x0e\x1c\xb9\x9a\x9a\xab\x52\x3f\xd9\xbc\x54\x22\x18\x1d\xca\x96\x8e\x97\x52\x17\x10\x1c\xef\xa5\xa6\xbc\xff\xbe\xa7\xa5\xd8\x1d\x10\x16\x45\x98\x8e\x95\xbf\x1e\x17\x20\x4d\xbc\xd2\x3f\x4e\xad\x9a\x99\xb4\x1e\x0e\x10\x2d\x9e\x90\x96\xb2\x2c\x22\x2f\x5c\x54\x2d\x24\x32\xaa\x94\x91\xa5\x24\x0f\x0f\x24\xaa\x98\x9b\xb2\x43\x3f\xcf\xc0\x3e\x1e\x18\x23\xaf\x92\x8e\x9c\x2f")); -snd($sock_a, $port_b, rtp(0, 1016, 5560, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1016, 5560, $ssrc, "\x13\x11\x21\xbd\xa2\xa8\xc3\xfa\xb9\xa6\xa9\x45\x19\x10\x1a\xc2\x94\x8e\x99\x4e\x1a\x18\x26\xeb\xba\xdd\x40\x7d\xa7\x99\x9c\xda\x19\x0e\x14\x4a\x99\x90\x99\xc9\x26\x23\x34\x6d\x4b\x2b\x25\x41\xa1\x92\x94\xb3\x1c\x0e\x12\x30\xa0\x96\x9d\xbe\x3b\x41\xcc\xc9\x34\x1c\x19\x2c\xa3\x8f\x8f\xa5\x23\x10\x13\x2a\xaf\xa0\xaa\xcd\xeb\xb4\xa6\xae\x31\x16\x11\x1f\xab\x90\x8e\x9e\x30\x18\x19\x2c\xc8\xb9\xf0\x43\xcc\xa2\x99\x9f\x3c\x14\x0e\x19\xbe\x95\x90\x9d\x4e\x22\x24\x3a\xfa\x43\x2a\x28\xec\x9d\x91\x98\xe4\x16\x0d\x16\x51\x9c\x96\xa0\xd7\x37\x45\xca\xda\x2c\x1b\x1b\x3d\x9c\x8e\x92\xb4\x1c\x0f\x16\x38\xa8\xa0\xad\xda\xdd\xb0\xa7\xb9\x28\x14\x13")); -# pause -snd($sock_a, $port_b, rtp(0, 1017, 5720, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1017, 5720, $ssrc, "\xff" x 160)); -snd($sock_a, $port_b, rtp(0, 1018, 5880, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1018, 5880, $ssrc, "\xff" x 160)); -snd($sock_a, $port_b, rtp(0, 1019, 6040, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1019, 6040, $ssrc, "\xff" x 160)); -snd($sock_a, $port_b, rtp(0, 1020, 6200, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1020, 6200, $ssrc, "\xff" x 160)); -snd($sock_a, $port_b, rtp(0, 1021, 6360, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1021, 6360, $ssrc, "\xff" x 160)); -# resume -snd($sock_a, $port_b, rtp(0, 1022, 6520, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1022, 6520, $ssrc, "\x00" x 160)); - - - - -# RFC payload type present - -($sock_a, $sock_b) = new_call([qw(198.51.100.1 6010)], [qw(198.51.100.3 6012)]); - -($port_a) = offer('multi- no transcoding, RFC payload type present', - { ICE => 'remove', replace => ['origin'], flags => ['inject DTMF'] }, < 'remove', replace => ['origin'], flags => ['inject DTMF'] }, < 'force-relay', flags => [qw(SDES-off)], 'transport-protocol' => 'UDP/TLS/RTP/SAVPF', + 'rtcp-mux' => [qw(accept offer)], 'via-branch' => 'z9hG4bK9463.af303705.113', + }, < ft(), code => '0', volume => 10, duration => 100 }); -$resp = rtpe_req('play DTMF', 'inject DTMF towards B', - { 'from-tag' => ft(), code => '1', volume => 6, duration => 100 }); - -snd($sock_a, $port_b, rtp(0, 1002, 3320, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(96 | 0x80, 1002, 3320, $ssrc, "\x00\x0a\x00\xa0")); -snd($sock_a, $port_b, rtp(0, 1003, 3480, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(96, 1003, 3320, $ssrc, "\x00\x0a\x01\x40")); -snd($sock_a, $port_b, rtp(0, 1004, 3640, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(96, 1004, 3320, $ssrc, "\x00\x0a\x01\xe0")); -snd($sock_a, $port_b, rtp(0, 1005, 3800, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(96, 1005, 3320, $ssrc, "\x00\x0a\x02\x80")); -snd($sock_a, $port_b, rtp(0, 1006, 3960, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(96, 1006, 3320, $ssrc, "\x00\x0a\x03\x20")); -snd($sock_a, $port_b, rtp(0, 1007, 4120, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(96, 1007, 3320, $ssrc, "\x00\x8a\x03\xc0")); -rcv($sock_b, $port_a, rtpm(96, 1008, 3320, $ssrc, "\x00\x8a\x03\xc0")); -rcv($sock_b, $port_a, rtpm(96, 1009, 3320, $ssrc, "\x00\x8a\x03\xc0")); -snd($sock_a, $port_b, rtp(0, 1008, 4280, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1010, 4280, $ssrc, "\x00" x 160)); -snd($sock_a, $port_b, rtp(0, 1009, 4440, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1011, 4440, $ssrc, "\x00" x 160)); -snd($sock_a, $port_b, rtp(0, 1010, 4600, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1012, 4600, $ssrc, "\x00" x 160)); -snd($sock_a, $port_b, rtp(0, 1011, 4760, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1013, 4760, $ssrc, "\x00" x 160)); -snd($sock_a, $port_b, rtp(0, 1012, 4920, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(96 | 0x80, 1014, 4920, $ssrc, "\x01\x06\x00\xa0")); -snd($sock_a, $port_b, rtp(0, 1013, 5080, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(96, 1015, 4920, $ssrc, "\x01\x06\x01\x40")); -snd($sock_a, $port_b, rtp(0, 1014, 5240, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(96, 1016, 4920, $ssrc, "\x01\x06\x01\xe0")); -snd($sock_a, $port_b, rtp(0, 1015, 5400, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(96, 1017, 4920, $ssrc, "\x01\x06\x02\x80")); -snd($sock_a, $port_b, rtp(0, 1016, 5560, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(96, 1018, 4920, $ssrc, "\x01\x06\x03\x20")); -snd($sock_a, $port_b, rtp(0, 1017, 5720, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(96, 1019, 4920, $ssrc, "\x01\x86\x03\xc0")); -rcv($sock_b, $port_a, rtpm(96, 1020, 4920, $ssrc, "\x01\x86\x03\xc0")); -rcv($sock_b, $port_a, rtpm(96, 1021, 4920, $ssrc, "\x01\x86\x03\xc0")); -snd($sock_a, $port_b, rtp(0, 1018, 5880, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1022, 5880, $ssrc, "\x00" x 160)); +is $ret1[2], $ret1[3], 'rtp rport 1'; +is $ret1[5], $ret1[6], 'rtp rport 2'; +if (0) { -# SDP in/out tests, various ICE options +# github issue 854 -new_call; +($sock_a, $sock_b) = new_call([qw(198.51.100.1 7326)], [qw(198.51.100.3 7328)]); -offer('plain SDP, no ICE', { ICE => 'remove' }, < 'remove', replace => ['origin'], codec => { transcode => ['PCMA'] } }, < 'remove' }, < 'remove', replace => ['origin'] }, < 'default' }, < 'remove', replace => ['origin'], codec => { transcode => ['PCMA'] } }, < 'default' }, < 'remove', replace => ['origin'] }, < 'optional' }, < 'remove', replace => ['origin'], flags => ['inject DTMF'] }, < 'remove' }, < 'remove', replace => ['origin'], flags => ['inject DTMF'] }, < 'remove' }, < ft(), code => '0', volume => 10, duration => 100 }); + +snd($sock_a, $port_b, rtp(0, 1002, 3320, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(96 | 0x80, 1002, 3320, $ssrc, "\x00\x0a\x00\xa0")); +snd($sock_a, $port_b, rtp(0, 1003, 3480, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(96, 1003, 3320, $ssrc, "\x00\x0a\x01\x40")); +snd($sock_a, $port_b, rtp(0, 1004, 3640, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(96, 1004, 3320, $ssrc, "\x00\x0a\x01\xe0")); +snd($sock_a, $port_b, rtp(0, 1005, 3800, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(96, 1005, 3320, $ssrc, "\x00\x0a\x02\x80")); +snd($sock_a, $port_b, rtp(0, 1006, 3960, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(96, 1006, 3320, $ssrc, "\x00\x0a\x03\x20")); +snd($sock_a, $port_b, rtp(0, 1007, 4120, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(96, 1007, 3320, $ssrc, "\x00\x8a\x03\xc0")); +rcv($sock_b, $port_a, rtpm(96, 1008, 3320, $ssrc, "\x00\x8a\x03\xc0")); +rcv($sock_b, $port_a, rtpm(96, 1009, 3320, $ssrc, "\x00\x8a\x03\xc0")); +snd($sock_a, $port_b, rtp(0, 1008, 4280, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1010, 4280, $ssrc, "\x00" x 160)); + + + +snd($sock_b, $port_a, rtp(0, 4000, 8000, 0x6543, "\x00" x 160)); +($ssrc) = rcv($sock_a, $port_b, rtpm(0, 4000, 8000, -1, "\x00" x 160)); +snd($sock_b, $port_a, rtp(0, 4001, 8160, 0x6543, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4001, 8160, $ssrc, "\x00" x 160)); + +$resp = rtpe_req('play DTMF', 'inject DTMF towards A', + { 'from-tag' => tt(), code => '*', volume => 10, duration => 100 }); + +snd($sock_b, $port_a, rtp(0, 4002, 8320, 0x6543, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(96 | 0x80, 4002, 8320, $ssrc, "\x0a\x0a\x00\xa0")); +snd($sock_b, $port_a, rtp(0, 4003, 8480, 0x6543, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(96, 4003, 8320, $ssrc, "\x0a\x0a\x01\x40")); +snd($sock_b, $port_a, rtp(0, 4004, 8640, 0x6543, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(96, 4004, 8320, $ssrc, "\x0a\x0a\x01\xe0")); +snd($sock_b, $port_a, rtp(0, 4005, 8800, 0x6543, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(96, 4005, 8320, $ssrc, "\x0a\x0a\x02\x80")); +snd($sock_b, $port_a, rtp(0, 4006, 8960, 0x6543, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(96, 4006, 8320, $ssrc, "\x0a\x0a\x03\x20")); +snd($sock_b, $port_a, rtp(0, 4007, 9120, 0x6543, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(96, 4007, 8320, $ssrc, "\x0a\x8a\x03\xc0")); +rcv($sock_a, $port_b, rtpm(96, 4008, 8320, $ssrc, "\x0a\x8a\x03\xc0")); +rcv($sock_a, $port_b, rtpm(96, 4009, 8320, $ssrc, "\x0a\x8a\x03\xc0")); +snd($sock_b, $port_a, rtp(0, 4008, 9280, 0x6543, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4010, 9280, $ssrc, "\x00" x 160)); + + + + + +# transcoding, RFC payload type present on both sides + +($sock_a, $sock_b) = new_call([qw(198.51.100.1 6110)], [qw(198.51.100.3 6112)]); + +($port_a) = offer('transcoding, RFC payload type present on both sides', + { ICE => 'remove', replace => ['origin'], flags => ['inject DTMF'], + codec => { transcode => ['PCMA'] }}, < 'optional' }, < 'remove', replace => ['origin'], flags => ['inject DTMF'] }, < '3.4.5.6', - flags => ['full-rtcp-attribute'], ICE => 'optional', }, < ft(), code => '0', volume => 10, duration => 100 }); + +snd($sock_a, $port_b, rtp(0, 1002, 3320, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(96 | 0x80, 1002, 3320, $ssrc, "\x00\x0a\x00\xa0")); +snd($sock_a, $port_b, rtp(0, 1003, 3480, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(96, 1003, 3320, $ssrc, "\x00\x0a\x01\x40")); +snd($sock_a, $port_b, rtp(0, 1004, 3640, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(96, 1004, 3320, $ssrc, "\x00\x0a\x01\xe0")); +snd($sock_a, $port_b, rtp(0, 1005, 3800, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(96, 1005, 3320, $ssrc, "\x00\x0a\x02\x80")); +snd($sock_a, $port_b, rtp(0, 1006, 3960, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(96, 1006, 3320, $ssrc, "\x00\x0a\x03\x20")); +snd($sock_a, $port_b, rtp(0, 1007, 4120, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(96, 1007, 3320, $ssrc, "\x00\x8a\x03\xc0")); +rcv($sock_b, $port_a, rtpm(96, 1008, 3320, $ssrc, "\x00\x8a\x03\xc0")); +rcv($sock_b, $port_a, rtpm(96, 1009, 3320, $ssrc, "\x00\x8a\x03\xc0")); +snd($sock_a, $port_b, rtp(0, 1008, 4280, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(8, 1010, 4280, $ssrc, "\x2a" x 160)); + + + +snd($sock_b, $port_a, rtp(8, 4000, 8000, 0x6543, "\x2a" x 160)); +($ssrc) = rcv($sock_a, $port_b, rtpm(0, 4000, 8000, -1, "\x00" x 160)); +snd($sock_b, $port_a, rtp(8, 4001, 8160, 0x6543, "\x2a" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4001, 8160, $ssrc, "\x00" x 160)); + +$resp = rtpe_req('play DTMF', 'inject DTMF towards A', + { 'from-tag' => tt(), code => '#', volume => -10, duration => 100 }); + +snd($sock_b, $port_a, rtp(8, 4002, 8320, 0x6543, "\x2a" x 160)); +rcv($sock_a, $port_b, rtpm(96 | 0x80, 4002, 8320, $ssrc, "\x0b\x0a\x00\xa0")); +snd($sock_b, $port_a, rtp(8, 4003, 8480, 0x6543, "\x2a" x 160)); +rcv($sock_a, $port_b, rtpm(96, 4003, 8320, $ssrc, "\x0b\x0a\x01\x40")); +snd($sock_b, $port_a, rtp(8, 4004, 8640, 0x6543, "\x2a" x 160)); +rcv($sock_a, $port_b, rtpm(96, 4004, 8320, $ssrc, "\x0b\x0a\x01\xe0")); +snd($sock_b, $port_a, rtp(8, 4005, 8800, 0x6543, "\x2a" x 160)); +rcv($sock_a, $port_b, rtpm(96, 4005, 8320, $ssrc, "\x0b\x0a\x02\x80")); +snd($sock_b, $port_a, rtp(8, 4006, 8960, 0x6543, "\x2a" x 160)); +rcv($sock_a, $port_b, rtpm(96, 4006, 8320, $ssrc, "\x0b\x0a\x03\x20")); +snd($sock_b, $port_a, rtp(8, 4007, 9120, 0x6543, "\x2a" x 160)); +rcv($sock_a, $port_b, rtpm(96, 4007, 8320, $ssrc, "\x0b\x8a\x03\xc0")); +rcv($sock_a, $port_b, rtpm(96, 4008, 8320, $ssrc, "\x0b\x8a\x03\xc0")); +rcv($sock_a, $port_b, rtpm(96, 4009, 8320, $ssrc, "\x0b\x8a\x03\xc0")); +snd($sock_b, $port_a, rtp(8, 4008, 9280, 0x6543, "\x2a" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4010, 9280, $ssrc, "\x00" x 160)); -new_call; -offer('ICE SDP, default ICE option', { ICE => 'optional' }, < 'remove', replace => ['origin'], flags => ['inject DTMF'] }, < 'optional' }, < 'remove', replace => ['origin'], flags => ['inject DTMF'] }, < 'force' }, < ft(), code => 'C', volume => 5, duration => 120, pause => 110 }); + +snd($sock_a, $port_b, rtp(0, 1002, 3320, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1002, 3320, $ssrc, "\xff\x93\x94\xbc\x2e\x56\xbf\x2b\x13\x1b\xa7\x8e\x98\x47\x25\x41\xe2\x24\x16\x2b\x99\x8e\x9f\x28\x1e\x3d\x5b\x23\x1c\xdf\x92\x8f\xb6\x1c\x1c\x40\x5d\x26\x25\xaa\x8f\x95\x3b\x15\x1d\x5e\xde\x2c\x38\x9d\x8f\x9e\x1f\x11\x20\xc0\xc1\x37\xdd\x99\x92\xb7\x15\x10\x2c\xac\xb5\x49\xb8\x97\x99\x37\x0f\x13\x58\xa0\xae\x67\xae\x99\xa4\x1f\x0d\x1a\xae\x9b\xad\x7b\xad\x9d\xbf\x16\x0e\x27\x9d\x98\xb0\x55\xb1\xa6\x3a\x11\x11\x63\x95\x98\xbf\x3e\xbb\xb4\x26\x10\x1a\xa9\x90\x9a\x4e\x30\xce\xd4\x1e\x12\x29\x99\x8e\xa1\x2d\x29\x6d\x4b\x1c\x18\xef\x91\x8f\xb6\x1f\x24\x57\x3e\x1d\x20\xa9\x8e\x95\x3e\x19\x23\x67\x3e\x21\x31\x9c\x8e\x9e\x22\x14\x26\xcd\x4a")); +snd($sock_a, $port_b, rtp(0, 1003, 3480, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1003, 3480, $ssrc, "\x2a\xdf\x96\x90\xb5\x17\x13\x2f\xb6\xf5\x36\xb1\x93\x96\x39\x10\x15\x55\xaa\xc8\x4c\xa7\x95\xa0\x1f\x0e\x1b\xb4\xa1\xbd\xed\xa4\x99\xbb\x15\x0e\x27\xa0\x9d\xbd\xda\xa4\x9f\x39\x10\x11\x58\x98\x9c\xc8\xf9\xa9\xac\x23\x0e\x19\xab\x92\x9e\x59\x4c\xb0\xca\x1b\x10\x27\x9a\x90\xa5\x35\x3a\xbe\x43\x18\x15\x6c\x92\x91\xb7\x26\x30\xd6\x32\x18\x1d\xa9\x8e\x96\x44\x1d\x2d\xfc\x2e\x1b\x2d\x9a\x8d\x9e\x25\x19\x2d\xe7\x2f\x20\xea\x94\x8f\xb3\x19\x17\x36\xc8\x36\x2c\xae\x90\x95\x3b\x12\x18\x55\xb7\x43\x3e\xa1\x91\x9e\x1f\x0f\x1d\xba\xac\x64\xe8\x9d\x95\xb7\x15\x0e\x29\xa6\xa6\xda\xc3\x9d\x9b\x39\x0f\x11\x51\x9c\xa2\xd8\xbe\x9f\xa7\x21\x0e\x18\xad")); +snd($sock_a, $port_b, rtp(0, 1004, 3640, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1004, 3640, $ssrc, "\x96\xa3\x68\xc4\xa5\xc2\x19\x0e\x26\x9c\x93\xa9\x3f\xdb\xae\x3e\x14\x12\x5b\x93\x93\xb9\x2e\x51\xbe\x2c\x14\x1b\xa9\x8f\x97\x4c\x25\x3f\xde\x25\x16\x2a\x9a\x8e\x9e\x29\x1e\x3b\x5e\x24\x1b\x7b\x92\x8f\xb2\x1c\x1c\x3e\x61\x27\x25\xac\x8f\x94\x3e\x15\x1c\x59\xdb\x2d\x37\x9e\x8f\x9d\x20\x11\x1f\xc2\xbf\x38\xea\x99\x92\xb4\x16\x10\x2b\xad\xb4\x49\xba\x98\x98\x3a\x0f\x12\x4e\xa1\xad\x68\xaf\x99\xa3\x20\x0d\x19\xb0\x9b\xac\x7b\xae\x9d\xbc\x17\x0e\x25\x9e\x98\xaf\x55\xb2\xa6\x3d\x12\x11\x52\x96\x97\xbd\x3e\xbc\xb3\x28\x10\x19\xab\x90\x9a\x54\x2f\xd0\xcf\x1f\x12\x27\x9a\x8e\xa0\x2e\x28\x66\x4e\x1d\x18\x62\x92\x8f\xb2\x20\x23\x53\x3f\x1d\x1f")); +snd($sock_a, $port_b, rtp(0, 1005, 3800, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1005, 3800, $ssrc, "\xab\x8e\x94\x44\x19\x22\x61\x40\x21\x2f\x9c\x8e\x9d\x23\x14\x25\xce\x4d\x2a\xf7\x96\x8f\xb1\x18\x13\x2e\xb7\xe8\x36\xb3\x94\x96\x3c\x10\x15\x4d\xaa\xc5\x4b\xa8\x95\x9f\x20\x0e\x1a\xb6\xa0\xbc\xf5\xa4\x99\xb8\x16\x0e\x26\xa1\x9d\xbb\xdd\xa5\x9f\x3c\x10\x10\x4c\x99\x9b\xc5\x78\xaa\xac\x24\x0f\x18\xac\x93\x9d\x5f\x4a\xb1\xc7\x1c\x0f\x25\x9b\x90\xa3\x36\x39\xbf\x47\x18\x14\x56\x92\x90\xb4\x27\x2f\xd7\x34\x18\x1c\xab\x8e\x95\x4b\x1d\x2c\xfe\x2f\x1b\x2c\x9b\x8d\x9d\x27\x19\x2c\xe7\x30\x20\x6d\x94\x8f\xaf\x1a\x17\x34\xc8\x37\x2b\xaf\x91\x94\x3f\x12\x18\x4e\xb6\x45\x3d\xa3\x91\x9e\x20\x0f\x1c\xbc\xab\x6c\xf5\x9e\x95\xb3\x16\x0e\x27\xa7\xa5")); +snd($sock_a, $port_b, rtp(0, 1006, 3960, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1006, 3960, $ssrc, "\xd6\xc6\x9d\x9b\x3d\x0f\x11\x49\x9c\xa1\xd4\xbf\x9f\xa6\x22\x0e\x18\xaf\x96\xa2\x6e\xc6\xa5\xbe\x19\x0e\x24\x9d\x93\xa8\x40\xe1\xae\x42\x15\x12\x4e\x94\x93\xb7\x2e\x4e\xbe\x2d\x14\x1a\xab\x8f\x97\x52\x25\x3e\xdc\x26\x16\x28\x9b\x8e\x9e\x2b\x1e\x3a\x61\x25\x1b\x5d\x93\x8f\xaf\x1d\x1c\x3d\x67\x27\x24\xad\x8f\x93\x45\x15\x1c\x53\xd7\x2d\x35\x9f\x8f\x9c\x22\x11\x1f\xc5\xbe\x38\x7a\x9a\x91\xb0\x17\x10\x29\xad\xb3\x4a\xbc\x98\x98\x3e\x10\x12\x48\xa1\xad\x6a\xb1\x9a\xa1\x21\x0e\x18\xb3\x9b\xab\x7d\xaf\x9d\xb9\x18\x0e\x23\x9f\x97\xae\x55\xb4\xa5\x40\x12\x10\x49\x96\x97\xbb\x3d\xbd\xb2\x29\x10\x18\xac\x90\x99\x5d\x2f\xd4\xcd\x1f\x12\x25\x9b")); +snd($sock_a, $port_b, rtp(0, 1007, 4120, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1007, 4120, $ssrc, "\x8e\x9f\x2f\x28\x5f\x51\x1d\x17\x52\x92\x8f\xaf\x20\x22\x50\x42\x1e\x1f\xad\x8e\x93\x4b\x19\x21\x5d\x42\x22\x2e\x9d\x8e\x9c\x25\x14\x24\xd0\x4f\x2a\x68\x97\x8f\xae\x18\x12\x2c\xb7\xdf\x36\xb6\x94\x95\x41\x11\x14\x48\xaa\xc3\x4a\xaa\x95\x9e\x21\x0e\x19\xb8\xa0\xba\xfe\xa5\x99\xb4\x17\x0e\x24\xa2\x9c\xba\xe0\xa6\x9e\x40\x10\x10\x45\x99\x9b\xc2\x6d\xaa\xab\x26\x0f\x17\xae\x93\x9c\x6a\x48\xb2\xc3\x1c\x0f\x23\x9c\x90\xa2\x37\x38\xbf\x4b\x19\x14\x4b\x93\x90\xb1\x27\x2e\xd8\x36\x19\x1c\xad\x8e\x94\x52\x1d\x2b\x7d\x30\x1b\x2a\x9c\x8d\x9c\x28\x19\x2b\xe7\x31\x20\x5a\x95\x8f\xad\x1a\x16\x32\xc8\x39\x2b\xb2\x91\x94\x46\x13\x17\x4a\xb6\x48\x3c")); +# pause +snd($sock_a, $port_b, rtp(0, 1008, 4280, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1008, 4280, $ssrc, "\xff" x 160)); +snd($sock_a, $port_b, rtp(0, 1009, 4440, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1009, 4440, $ssrc, "\xff" x 160)); +snd($sock_a, $port_b, rtp(0, 1010, 4600, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1010, 4600, $ssrc, "\xff" x 160)); +snd($sock_a, $port_b, rtp(0, 1011, 4760, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1011, 4760, $ssrc, "\xff" x 160)); +snd($sock_a, $port_b, rtp(0, 1012, 4920, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1012, 4920, $ssrc, "\xff" x 160)); +snd($sock_a, $port_b, rtp(0, 1013, 5080, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1013, 5080, $ssrc, "\xff" x 80 . "\x00" x 80)); + + + +snd($sock_b, $port_a, rtp(0, 4000, 8000, 0x6543, "\x00" x 160)); +($ssrc) = rcv($sock_a, $port_b, rtpm(0, 4000, 8000, -1, "\x00" x 160)); +snd($sock_b, $port_a, rtp(0, 4001, 8160, 0x6543, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4001, 8160, $ssrc, "\x00" x 160)); + +$resp = rtpe_req('play DTMF', 'inject DTMF towards A', + { 'from-tag' => tt(), code => '4', volume => 3, duration => 150, pause => 100 }); + +snd($sock_b, $port_a, rtp(0, 4002, 8320, 0x6543, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4002, 8320, $ssrc, "\xff\x90\x8a\x93\xd9\x1b\x18\x27\x65\xe5\x33\x29\x4c\x9e\x8f\x91\xb8\x15\x09\x0d\x32\x98\x8e\x96\xbb\x2c\x2b\x4c\xd8\x34\x1c\x18\x2e\x9d\x8c\x8c\xa5\x1a\x0b\x0d\x27\xa3\x97\x9e\xbd\x4f\xc4\xaa\xb2\x2c\x12\x0e\x1e\xa1\x8b\x8a\x9c\x25\x0e\x10\x25\xb7\xa7\xb7\x5e\xcb\xa2\x98\x9f\x30\x0f\x0a\x16\xae\x8d\x8a\x98\x3a\x18\x19\x2c\xdd\xfd\x30\x2b\xce\x99\x8e\x95\x4c\x0f\x09\x10\xdf\x93\x8e\x9a\xec\x28\x2c\x56\xee\x2d\x1a\x1a\x48\x97\x8b\x8e\xba\x14\x0a\x0f\x39\x9d\x96\xa1\xcd\x4e\xbe\xab\xbe\x23\x10\x10\x2b\x99\x8a\x8c\xa7\x1b\x0d\x12\x2f\xad\xa7\xbc\x5e\xbd\x9f\x99\xa8\x23\x0d\x0b\x1d\x9f\x8b\x8c\x9f\x29\x16\x1b\x34\xcd\x60\x2f\x2f\xb6\x96")); +snd($sock_b, $port_a, rtp(0, 4003, 8480, 0x6543, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4003, 8480, $ssrc, "\x8e\x9b\x2b\x0c\x09\x17\xae\x8f\x8e\x9e\x3f\x25\x2e\x65\x5c\x28\x1a\x1e\xc2\x92\x8a\x92\x44\x0f\x0a\x14\xd6\x99\x97\xa6\x7c\x4e\xba\xad\xe5\x1d\x0f\x13\x49\x92\x89\x8e\xbe\x15\x0d\x16\x43\xa8\xa7\xc1\x66\xb5\x9d\x9a\xb6\x1b\x0c\x0d\x2b\x98\x8a\x8d\xab\x1f\x15\x1d\x3f\xc7\x52\x2e\x39\xaa\x93\x8f\xa3\x1e\x0b\x0b\x1e\x9f\x8d\x8f\xa7\x30\x23\x31\x7c\x4a\x24\x1a\x24\xac\x8e\x8b\x99\x28\x0c\x0a\x1a\xb0\x96\x98\xac\x4f\x53\xb7\xaf\x44\x19\x0f\x18\xba\x8e\x89\x93\x3f\x10\x0d\x1a\xd5\xa3\xa8\xca\xf9\xae\x9c\x9d\xec\x16\x0b\x10\x4e\x91\x89\x90\xc6\x1a\x14\x20\x55\xc3\x4a\x2f\x49\xa2\x91\x92\xb2\x17\x09\x0c\x2d\x99\x8d\x92\xb3\x29\x23\x36\xf2")); +snd($sock_b, $port_a, rtp(0, 4004, 8640, 0x6543, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4004, 8640, $ssrc, "\x3e\x20\x1b\x2d\xa0\x8d\x8c\xa1\x1c\x0a\x0c\x22\xa3\x94\x9a\xb5\x44\x5c\xb5\xb6\x32\x16\x0f\x1e\xa6\x8c\x8a\x99\x28\x0e\x0e\x20\xb7\xa1\xab\xd4\xdb\xaa\x9c\xa1\x38\x11\x0b\x15\xb5\x8d\x8a\x96\x3f\x16\x15\x26\xdd\xc2\x43\x31\xdf\x9d\x90\x96\x6d\x11\x09\x0f\x5a\x93\x8c\x97\xd2\x23\x23\x3b\xf6\x37\x1f\x1d\x40\x9a\x8c\x8e\xb2\x15\x09\x0e\x31\x9c\x93\x9c\xc2\x3e\x74\xb4\xbf\x29\x14\x11\x29\x9b\x8a\x8b\xa3\x1c\x0d\x0f\x2a\xab\x9f\xad\xe0\xcc\xa6\x9c\xa9\x28\x0e\x0c\x1c\xa2\x8b\x8b\x9c\x2a\x14\x17\x2c\xc6\xc4\x3e\x36\xbd\x99\x90\x9b\x30\x0d\x09\x15\xb3\x8f\x8d\x9b\x42\x1f\x25\x42\x70\x30\x1e\x1f\xcf\x95\x8b\x92\x58\x0f\x09\x12\x6f\x98\x93")); +snd($sock_b, $port_a, rtp(0, 4005, 8800, 0x6543, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4005, 8800, $ssrc, "\x9f\xe5\x3b\xe2\xb5\xd9\x21\x12\x14\x3e\x95\x89\x8d\xb6\x16\x0c\x13\x3a\xa4\x9f\xb1\xf1\xc0\xa3\x9d\xb4\x1e\x0d\x0d\x27\x99\x8a\x8c\xa7\x1f\x12\x19\x37\xbc\xc8\x3c\x3c\xaf\x97\x91\xa2\x21\x0b\x0a\x1c\xa2\x8d\x8e\xa2\x2f\x1e\x28\x4c\x5d\x2c\x1e\x25\xb0\x90\x8c\x98\x2c\x0c\x0a\x18\xb4\x94\x94\xa6\x4d\x3a\xd4\xb8\x4f\x1d\x11\x18\xc5\x8f\x89\x91\x4d\x10\x0c\x17\xec\x9f\xa0\xb8\xff\xba\xa1\x9f\xd3\x19\x0c\x0f\x3f\x92\x89\x8f\xbb\x19\x11\x1c\x48\xb8\xce\x3b\x4a\xa8\x95\x93\xaf\x19\x0a\x0c\x29\x99\x8c\x8f\xad\x27\x1d\x2b\x59\x4f\x29\x1e\x2d\xa5\x8e\x8d\x9f\x1e\x0b\x0b\x1e\xa4\x91\x96\xad\x3e\x3b\xcc\xbc\x3a\x1a\x12\x1e\xaa\x8d\x8a\x98\x2b")); +snd($sock_b, $port_a, rtp(0, 4006, 8960, 0x6543, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4006, 8960, $ssrc, "\x0e\x0c\x1d\xb8\x9d\xa2\xbe\xf9\xb4\xa0\xa3\x3f\x14\x0c\x14\xbd\x8e\x89\x93\x49\x15\x12\x1f\xe7\xb5\xd9\x3c\x7c\xa1\x93\x97\xd5\x13\x09\x0e\x45\x93\x8b\x93\xc4\x20\x1d\x2e\x6b\x46\x26\x1f\x3d\x9d\x8d\x8e\xae\x17\x09\x0d\x2c\x9c\x90\x98\xba\x36\x3d\xc7\xc4\x2e\x17\x13\x27\x9e\x8b\x8b\x9f\x1e\x0c\x0e\x25\xaa\x9c\xa5\xc8\xe8\xae\xa0\xaa\x2d\x10\x0c\x1b\xa6\x8c\x8a\x9a\x2c\x12\x13\x27\xc3\xb3\xed\x3e\xc8\x9d\x93\x9b\x38\x0f\x09\x13\xba\x8f\x8b\x98\x4a\x1d\x1e\x34\xf9\x3e\x24\x23\xea\x98\x8c\x92\xdf\x10\x09\x0f\x4d\x97\x90\x9c\xd2\x31\x3f\xc5\xd6\x28\x16\x16\x39\x97\x8a\x8d\xaf\x17\x0b\x10\x32\xa2\x9b\xa8\xd6\xd9\xac\xa1\xb3\x22\x0e\x0e")); +snd($sock_b, $port_a, rtp(0, 4007, 9120, 0x6543, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4007, 9120, $ssrc, "\x24\x9b\x8a\x8b\xa2\x1f\x10\x15\x2f\xb8\xb4\x68\x43\xb8\x9a\x94\xa1\x25\x0c\x0a\x1a\xa5\x8d\x8c\x9e\x30\x1b\x1f\x3c\xee\x38\x23\x28\xb8\x93\x8d\x97\x31\x0d\x09\x15\xb9\x93\x90\xa0\x4f\x2f\x46\xc4\x5e\x21\x15\x19\xd7\x91\x89\x90\x7b\x10\x0b\x14\x5b\x9d\x9c\xad\xed\xcd\xa9\xa3\xca\x1c\x0d\x10\x38\x94\x89\x8e\xb3\x19\x0f\x18\x3e\xb0\xb5\x59\x4d\xae\x98\x95\xad\x1c\x0b\x0c\x25\x9b\x8b\x8e\xa9\x26\x1a\x22\x46\xf5\x33\x23\x2e\xaa\x90\x8d\x9e\x21\x0b\x0a\x1c\xa6\x90\x92\xa8\x3b\x2e\x4d\xc7\x43\x1e\x15\x1e\xaf\x8e\x8a\x96\x2e\x0e\x0b\x1a\xbb\x9b\x9d\xb2\x68\xc5\xa8\xa7\x4c\x17\x0d\x14\xcb\x8f\x89\x91\x5e\x14\x0f\x1c\x6e\xad\xb8\x52\x68\xa8")); +snd($sock_b, $port_a, rtp(0, 4008, 9280, 0x6543, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4008, 9280, $ssrc, "\x97\x98\xc7\x16\x0a\x0e\x3a\x94\x8a\x90\xbb\x1e\x1a\x27\x56\x6f\x2f\x25\x3b\xa0\x8e\x8f\xaa\x19\x09\x0c\x28\x9c\x8f\x95\xb2\x31\x2e\x59\xcc\x37\x1b\x16\x26\xa1\x8c\x8b\x9d\x1f\x0c\x0c\x20\xab\x99\x9e\xbb\x5d\xbe\xa7\xac\x32\x13\x0d\x1a\xab\x8c\x89\x97\x2e\x10\x10\x21\xc3\xab\xbc\x4f\xd4\xa2\x96\x9c\x3f\x10\x0a\x12\xc4\x8f\x8a\x95\x57\x1b\x1a\x2b\xfd\x5d\x2d\x27\x62\x9b\x8e\x92\xc9\x12\x09\x0e\x3f\x97\x8e\x98\xc6\x2c\x2f\x6b\xd9\x2e\x1a\x18\x34\x9a\x8b\x8d\xab\x18\x0a\x0e\x2d\xa1\x98\xa1\xc7\x5b\xb9\xa7\xb4\x27\x10\x0e\x22\x9d\x8a\x8b\x9f\x20\x0e\x12\x2a\xb4\xaa\xc0\x50\xc0\x9e\x97\xa1\x2a\x0e\x0a\x19\xa8\x8c\x8b\x9b\x31\x18\x1b\x31")); +snd($sock_b, $port_a, rtp(0, 4009, 9440, 0x6543, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4009, 9440, $ssrc, "\xda\x50\x2c\x2b\xc0\x97\x8e\x97\x39\x0e\x09\x13\xbf\x92\x8e\x9c\x57\x29\x31\xef\x72\x28\x19\x1b\x6d\x94\x8a\x8f\xce\x11\x0a\x11\x48\x9c\x98\xa5\xdc\x5e\xb5\xa9\xc6\x1f\x0f\x10\x31\x96\x89\x8d\xad\x19\x0e\x15\x37\xac\xaa\xc8\x57\xb7\x9c\x98\xac\x1e\x0c\x0c\x21\x9c\x8b\x8d\xa4\x25\x17\x1d\x3b\xcf\x48\x2b\x30\xae\x93\x8e" . "\xff" x 80)); +# pause +snd($sock_b, $port_a, rtp(0, 4010, 9600, 0x6543, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4010, 9600, $ssrc, "\xff" x 160)); +snd($sock_b, $port_a, rtp(0, 4011, 9760, 0x6543, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4011, 9760, $ssrc, "\xff" x 160)); +snd($sock_b, $port_a, rtp(0, 4012, 9920, 0x6543, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4012, 9920, $ssrc, "\xff" x 160)); +snd($sock_b, $port_a, rtp(0, 4013, 10080, 0x6543, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4013, 10080, $ssrc, "\xff" x 160)); +snd($sock_b, $port_a, rtp(0, 4014, 10240, 0x6543, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4014, 10240, $ssrc, "\xff" x 80 . "\x00" x 80)); + + + + +# transcoding, no RFC payload type present + +($sock_a, $sock_b) = new_call([qw(198.51.100.1 6018)], [qw(198.51.100.3 6020)]); + +($port_a) = offer('transcoding, no RFC payload type present', + { ICE => 'remove', replace => ['origin'], flags => ['inject DTMF'], + codec => { transcode => ['PCMA'] } }, < 'optional' }, < 'remove', replace => ['origin'], flags => ['inject DTMF'] }, < 'force' }, < ft(), code => 'C', volume => 5, duration => 120 }); + +snd($sock_a, $port_b, rtp(0, 1002, 3320, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(8, 1002, 3320, $ssrc, "\xd5\xb9\xbe\x97\x05\x70\xea\x01\x3e\x31\x82\xa5\xb2\x63\x0f\x69\xc1\x0f\x3d\x06\xb3\xa4\x8a\x03\x35\x14\x75\x0e\x36\xcc\xb8\xa5\x9d\x36\x36\x68\x49\x0d\x0c\x81\xa5\xbf\x16\x3f\x37\x4f\xcf\x07\x13\xb4\xa5\xb4\x0a\x3b\x0b\xeb\xe9\x12\xc9\xb3\xb8\x92\x3c\x3a\x07\x87\x9c\x61\x93\xb2\xb3\x12\x25\x39\x76\x8b\x85\x5a\x85\xb3\x8e\x35\x24\x30\x85\xb1\x87\x57\x84\xb7\xeb\x3c\x24\x0d\xb4\xb2\x9b\x70\x98\x8c\x11\x3b\x38\x41\xbf\xb2\xeb\x15\x96\x9f\x0d\x3a\x30\x83\xba\xb1\x7b\x1b\xfa\xf2\x34\x39\x03\xb0\xa5\x88\x04\x03\x5f\x67\x37\x32\xdd\xb8\xba\x9d\x35\x0e\x71\x15\x37\x0a\x80\xa4\xbf\x15\x33\x09\x45\x15\x0b\x18\xb6\xa4\xb4\x08\x3f\x0d\xe5\x66")); +snd($sock_a, $port_b, rtp(0, 1003, 3480, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(8, 1003, 3480, $ssrc, "\x00\xcd\xbc\xba\x9c\x3d\x39\x1a\x9d\xd1\x1d\x98\xbe\xbd\x10\x3a\x3f\x73\x80\xe0\x64\x82\xbf\x8b\x35\x24\x31\x9f\x8b\x94\xdf\x8e\xb3\x96\x3c\x24\x02\x8b\xb7\x94\xf4\x8f\xb5\x10\x3a\x3b\x76\xb2\xb6\xe0\xd6\x80\x87\x09\x25\x33\x81\xb9\xb4\x74\x64\x9b\xe6\x31\x3a\x0d\xb1\xba\x8f\x1c\x11\x95\x6f\x32\x3f\x5e\xb8\xbb\x92\x0d\x1a\xf0\x19\x32\x37\x83\xa4\xbc\x6d\x37\x07\xd4\x04\x31\x07\xb1\xa4\xb4\x0c\x33\x04\xc5\x05\x0b\xd8\xbe\xa5\x9e\x30\x3d\x1d\xe0\x1d\x06\x84\xbb\xbf\x16\x38\x33\x73\x92\x6f\x15\x88\xbb\xb5\x35\x25\x37\x91\x86\x46\xda\xb7\xbf\x92\x3c\x25\x03\x8d\x8c\xf4\xef\xb7\xb6\x10\x25\x3b\x7f\xb6\x89\xf6\x95\xb5\x82\x0b\x24\x33\x84")); +snd($sock_a, $port_b, rtp(0, 1004, 3640, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(8, 1004, 3640, $ssrc, "\xbd\x8e\x5a\xec\x8c\xee\x33\x24\x0c\xb6\xbe\x80\x6b\xf5\x85\x6a\x3f\x39\x4a\xbe\xbe\x90\x05\x7f\x95\x06\x3e\x31\x80\xa5\xbd\x64\x0f\x6b\xcc\x0c\x3d\x00\xb0\xa4\xb5\x00\x34\x16\x4e\x0e\x36\x57\xb9\xa5\x99\x36\x36\x6a\x43\x0d\x0f\x86\xa5\xbe\x15\x3f\x36\x77\xf5\x07\x12\xb4\xa5\xb4\x0b\x3b\x0a\xee\xeb\x13\xd8\xb0\xb8\x9f\x3c\x3a\x01\x87\x9f\x66\x91\xb2\xb3\x11\x25\x39\x7a\x8b\x84\x5b\x9a\xb0\x89\x0a\x24\x33\x9b\xb1\x87\x54\x85\xb7\x97\x3d\x24\x0c\xb4\xb2\x9a\x73\x99\x8c\x14\x38\x3b\x7c\xbc\xbd\x94\x15\x97\x9e\x02\x3a\x33\x81\xba\xb0\x73\x1a\xfe\xf9\x35\x39\x02\xb1\xa4\x8a\x05\x03\x44\x7a\x37\x32\x40\xb8\xa5\x99\x0a\x0e\x72\x6b\x34\x35")); +snd($sock_a, $port_b, rtp(0, 1005, 3800, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(8, 1005, 3800, $ssrc, "\x81\xa4\xbe\x6c\x33\x08\x43\x68\x08\x1a\xb7\xa4\xb7\x0e\x3f\x0c\xfb\x65\x00\xd1\xbd\xba\x98\x32\x39\x04\x92\xdb\x1d\x9e\xbe\xbc\x17\x3a\x3f\x65\x80\xed\x67\x83\xbf\xb5\x0a\x24\x30\x9d\x8b\x97\xd0\x8f\xb3\x93\x3c\x24\x0c\x88\xb7\x96\xc9\x8c\xb5\x17\x3a\x3a\x64\xb3\xb6\xed\x56\x80\x86\x0f\x25\x32\x87\xb9\xb7\x4d\x66\x98\xe3\x36\x3a\x0c\xb1\xba\x8e\x1d\x10\xea\x63\x33\x3f\x70\xb9\xbb\x9f\x0d\x05\xf1\x1f\x33\x36\x81\xa4\xbf\x67\x34\x06\xd5\x05\x31\x06\xb6\xa4\xb7\x0d\x33\x07\xc5\x1a\x0a\x5f\xbe\xa5\x9a\x30\x3d\x1f\xe0\x12\x06\x9a\xbb\xbf\x6b\x39\x32\x7b\x9d\x62\x14\x89\xbb\xb4\x0b\x25\x36\x97\x86\x5e\xd1\xb4\xbf\x9e\x3c\x24\x0d\x82\x8c")); +snd($sock_a, $port_b, rtp(0, 1006, 3960, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(8, 1006, 3960, $ssrc, "\xf0\xe2\xb7\xb1\x14\x3a\x3b\x61\xb6\x88\xf3\xeb\xb5\x8d\x09\x24\x32\x85\xbd\x89\x5c\xe2\x8c\x95\x30\x24\x0e\xb7\xb9\x83\x68\xc3\x85\x6e\x3f\x38\x7a\xbe\xb9\x92\x05\x7a\x95\x07\x3e\x30\x86\xa5\xbd\x7c\x0f\x15\xcb\x0d\x3d\x03\xb1\xa4\xb4\x01\x34\x11\x40\x0f\x36\x48\xb9\xa5\x85\x37\x36\x14\x45\x02\x0f\x84\xa5\xbe\x6d\x3c\x36\x7d\xf1\x04\x1c\xb5\xa5\xb7\x09\x3b\x35\xed\xea\x13\x57\xb0\xb8\x9b\x3d\x3a\x00\x84\x9e\x66\x97\xb2\xb2\x15\x3a\x38\x60\x8b\x87\x58\x98\xb0\x88\x08\x24\x32\x9e\xb1\x86\x54\x9a\xb7\x90\x32\x24\x0e\xb5\xb2\x84\x73\x9f\x8c\x68\x38\x3b\x61\xbc\xbd\x96\x14\x94\x99\x03\x3b\x32\x87\xba\xb3\x48\x1a\xf2\xe5\x0a\x39\x0c\xb1")); +snd($sock_a, $port_b, rtp(0, 1007, 4120, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(8, 1007, 4120, $ssrc, "\xa4\xb5\x1a\x02\x4c\x7f\x37\x32\x7c\xb9\xa5\x9a\x0a\x09\x7e\x6e\x34\x35\x87\xa5\xbe\x67\x33\x0b\x48\x6e\x08\x05\xb7\xa4\xb6\x0f\x3f\x0e\xfe\x79\x00\x5a\xbd\xa5\x85\x32\x39\x07\x92\xcd\x1d\x9d\xbe\xbc\x69\x3b\x3e\x60\x80\xef\x66\x80\xbf\xb5\x08\x24\x30\x90\x8b\x91\xd5\x8c\xb3\x9f\x3d\x24\x0e\x89\xb7\x91\xc2\x8c\xb5\x68\x3b\x3a\x6d\xb3\xb1\xee\x5c\x81\x81\x0c\x25\x3d\x85\xb9\xb7\x58\x60\x99\xef\x37\x3a\x0e\xb6\xba\x89\x12\x13\xeb\x67\x33\x3e\x67\xb9\xba\x98\x02\x05\xf7\x1d\x33\x36\x87\xa4\xbe\x7c\x34\x01\x54\x1a\x31\x01\xb6\xa4\xb6\x03\x33\x06\xda\x18\x0a\x75\xbf\xa5\x84\x31\x3d\x19\xe0\x10\x01\x99\xbb\xbe\x62\x39\x3d\x66\x9d\x60\x17")); +# pause +snd($sock_a, $port_b, rtp(0, 1008, 4280, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(8, 1008, 4280, $ssrc, "\xd5" x 160)); +snd($sock_a, $port_b, rtp(0, 1009, 4440, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(8, 1009, 4440, $ssrc, "\xd5" x 160)); +snd($sock_a, $port_b, rtp(0, 1010, 4600, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(8, 1010, 4600, $ssrc, "\xd5" x 160)); +snd($sock_a, $port_b, rtp(0, 1011, 4760, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(8, 1011, 4760, $ssrc, "\xd5" x 160)); +snd($sock_a, $port_b, rtp(0, 1012, 4920, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(8, 1012, 4920, $ssrc, "\xd5" x 160)); +snd($sock_a, $port_b, rtp(0, 1013, 5080, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(8, 1013, 5080, $ssrc, "\x2a" x 160)); + + + + +snd($sock_b, $port_a, rtp(8, 4000, 8000, 0x6543, "\x2a" x 160)); +($ssrc) = rcv($sock_a, $port_b, rtpm(0, 4000, 8000, -1, "\x00" x 160)); +snd($sock_b, $port_a, rtp(8, 4001, 8160, 0x6543, "\x2a" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4001, 8160, $ssrc, "\x00" x 160)); + +$resp = rtpe_req('play DTMF', 'inject DTMF towards A', + { 'from-tag' => tt(), code => '4', volume => 3, duration => 150 }); + +snd($sock_b, $port_a, rtp(8, 4002, 8320, 0x6543, "\x2a" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4002, 8320, $ssrc, "\xff\x90\x8a\x93\xd9\x1b\x18\x27\x65\xe5\x33\x29\x4c\x9e\x8f\x91\xb8\x15\x09\x0d\x32\x98\x8e\x96\xbb\x2c\x2b\x4c\xd8\x34\x1c\x18\x2e\x9d\x8c\x8c\xa5\x1a\x0b\x0d\x27\xa3\x97\x9e\xbd\x4f\xc4\xaa\xb2\x2c\x12\x0e\x1e\xa1\x8b\x8a\x9c\x25\x0e\x10\x25\xb7\xa7\xb7\x5e\xcb\xa2\x98\x9f\x30\x0f\x0a\x16\xae\x8d\x8a\x98\x3a\x18\x19\x2c\xdd\xfd\x30\x2b\xce\x99\x8e\x95\x4c\x0f\x09\x10\xdf\x93\x8e\x9a\xec\x28\x2c\x56\xee\x2d\x1a\x1a\x48\x97\x8b\x8e\xba\x14\x0a\x0f\x39\x9d\x96\xa1\xcd\x4e\xbe\xab\xbe\x23\x10\x10\x2b\x99\x8a\x8c\xa7\x1b\x0d\x12\x2f\xad\xa7\xbc\x5e\xbd\x9f\x99\xa8\x23\x0d\x0b\x1d\x9f\x8b\x8c\x9f\x29\x16\x1b\x34\xcd\x60\x2f\x2f\xb6\x96")); +snd($sock_b, $port_a, rtp(8, 4003, 8480, 0x6543, "\x2a" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4003, 8480, $ssrc, "\x8e\x9b\x2b\x0c\x09\x17\xae\x8f\x8e\x9e\x3f\x25\x2e\x65\x5c\x28\x1a\x1e\xc2\x92\x8a\x92\x44\x0f\x0a\x14\xd6\x99\x97\xa6\x7c\x4e\xba\xad\xe5\x1d\x0f\x13\x49\x92\x89\x8e\xbe\x15\x0d\x16\x43\xa8\xa7\xc1\x66\xb5\x9d\x9a\xb6\x1b\x0c\x0d\x2b\x98\x8a\x8d\xab\x1f\x15\x1d\x3f\xc7\x52\x2e\x39\xaa\x93\x8f\xa3\x1e\x0b\x0b\x1e\x9f\x8d\x8f\xa7\x30\x23\x31\x7c\x4a\x24\x1a\x24\xac\x8e\x8b\x99\x28\x0c\x0a\x1a\xb0\x96\x98\xac\x4f\x53\xb7\xaf\x44\x19\x0f\x18\xba\x8e\x89\x93\x3f\x10\x0d\x1a\xd5\xa3\xa8\xca\xf9\xae\x9c\x9d\xec\x16\x0b\x10\x4e\x91\x89\x90\xc6\x1a\x14\x20\x55\xc3\x4a\x2f\x49\xa2\x91\x92\xb2\x17\x09\x0c\x2d\x99\x8d\x92\xb3\x29\x23\x36\xf2")); +snd($sock_b, $port_a, rtp(8, 4004, 8640, 0x6543, "\x2a" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4004, 8640, $ssrc, "\x3e\x20\x1b\x2d\xa0\x8d\x8c\xa1\x1c\x0a\x0c\x22\xa3\x94\x9a\xb5\x44\x5c\xb5\xb6\x32\x16\x0f\x1e\xa6\x8c\x8a\x99\x28\x0e\x0e\x20\xb7\xa1\xab\xd4\xdb\xaa\x9c\xa1\x38\x11\x0b\x15\xb5\x8d\x8a\x96\x3f\x16\x15\x26\xdd\xc2\x43\x31\xdf\x9d\x90\x96\x6d\x11\x09\x0f\x5a\x93\x8c\x97\xd2\x23\x23\x3b\xf6\x37\x1f\x1d\x40\x9a\x8c\x8e\xb2\x15\x09\x0e\x31\x9c\x93\x9c\xc2\x3e\x74\xb4\xbf\x29\x14\x11\x29\x9b\x8a\x8b\xa3\x1c\x0d\x0f\x2a\xab\x9f\xad\xe0\xcc\xa6\x9c\xa9\x28\x0e\x0c\x1c\xa2\x8b\x8b\x9c\x2a\x14\x17\x2c\xc6\xc4\x3e\x36\xbd\x99\x90\x9b\x30\x0d\x09\x15\xb3\x8f\x8d\x9b\x42\x1f\x25\x42\x70\x30\x1e\x1f\xcf\x95\x8b\x92\x58\x0f\x09\x12\x6f\x98\x93")); +snd($sock_b, $port_a, rtp(8, 4005, 8800, 0x6543, "\x2a" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4005, 8800, $ssrc, "\x9f\xe5\x3b\xe2\xb5\xd9\x21\x12\x14\x3e\x95\x89\x8d\xb6\x16\x0c\x13\x3a\xa4\x9f\xb1\xf1\xc0\xa3\x9d\xb4\x1e\x0d\x0d\x27\x99\x8a\x8c\xa7\x1f\x12\x19\x37\xbc\xc8\x3c\x3c\xaf\x97\x91\xa2\x21\x0b\x0a\x1c\xa2\x8d\x8e\xa2\x2f\x1e\x28\x4c\x5d\x2c\x1e\x25\xb0\x90\x8c\x98\x2c\x0c\x0a\x18\xb4\x94\x94\xa6\x4d\x3a\xd4\xb8\x4f\x1d\x11\x18\xc5\x8f\x89\x91\x4d\x10\x0c\x17\xec\x9f\xa0\xb8\xff\xba\xa1\x9f\xd3\x19\x0c\x0f\x3f\x92\x89\x8f\xbb\x19\x11\x1c\x48\xb8\xce\x3b\x4a\xa8\x95\x93\xaf\x19\x0a\x0c\x29\x99\x8c\x8f\xad\x27\x1d\x2b\x59\x4f\x29\x1e\x2d\xa5\x8e\x8d\x9f\x1e\x0b\x0b\x1e\xa4\x91\x96\xad\x3e\x3b\xcc\xbc\x3a\x1a\x12\x1e\xaa\x8d\x8a\x98\x2b")); +snd($sock_b, $port_a, rtp(8, 4006, 8960, 0x6543, "\x2a" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4006, 8960, $ssrc, "\x0e\x0c\x1d\xb8\x9d\xa2\xbe\xf9\xb4\xa0\xa3\x3f\x14\x0c\x14\xbd\x8e\x89\x93\x49\x15\x12\x1f\xe7\xb5\xd9\x3c\x7c\xa1\x93\x97\xd5\x13\x09\x0e\x45\x93\x8b\x93\xc4\x20\x1d\x2e\x6b\x46\x26\x1f\x3d\x9d\x8d\x8e\xae\x17\x09\x0d\x2c\x9c\x90\x98\xba\x36\x3d\xc7\xc4\x2e\x17\x13\x27\x9e\x8b\x8b\x9f\x1e\x0c\x0e\x25\xaa\x9c\xa5\xc8\xe8\xae\xa0\xaa\x2d\x10\x0c\x1b\xa6\x8c\x8a\x9a\x2c\x12\x13\x27\xc3\xb3\xed\x3e\xc8\x9d\x93\x9b\x38\x0f\x09\x13\xba\x8f\x8b\x98\x4a\x1d\x1e\x34\xf9\x3e\x24\x23\xea\x98\x8c\x92\xdf\x10\x09\x0f\x4d\x97\x90\x9c\xd2\x31\x3f\xc5\xd6\x28\x16\x16\x39\x97\x8a\x8d\xaf\x17\x0b\x10\x32\xa2\x9b\xa8\xd6\xd9\xac\xa1\xb3\x22\x0e\x0e")); +snd($sock_b, $port_a, rtp(8, 4007, 9120, 0x6543, "\x2a" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4007, 9120, $ssrc, "\x24\x9b\x8a\x8b\xa2\x1f\x10\x15\x2f\xb8\xb4\x68\x43\xb8\x9a\x94\xa1\x25\x0c\x0a\x1a\xa5\x8d\x8c\x9e\x30\x1b\x1f\x3c\xee\x38\x23\x28\xb8\x93\x8d\x97\x31\x0d\x09\x15\xb9\x93\x90\xa0\x4f\x2f\x46\xc4\x5e\x21\x15\x19\xd7\x91\x89\x90\x7b\x10\x0b\x14\x5b\x9d\x9c\xad\xed\xcd\xa9\xa3\xca\x1c\x0d\x10\x38\x94\x89\x8e\xb3\x19\x0f\x18\x3e\xb0\xb5\x59\x4d\xae\x98\x95\xad\x1c\x0b\x0c\x25\x9b\x8b\x8e\xa9\x26\x1a\x22\x46\xf5\x33\x23\x2e\xaa\x90\x8d\x9e\x21\x0b\x0a\x1c\xa6\x90\x92\xa8\x3b\x2e\x4d\xc7\x43\x1e\x15\x1e\xaf\x8e\x8a\x96\x2e\x0e\x0b\x1a\xbb\x9b\x9d\xb2\x68\xc5\xa8\xa7\x4c\x17\x0d\x14\xcb\x8f\x89\x91\x5e\x14\x0f\x1c\x6e\xad\xb8\x52\x68\xa8")); +snd($sock_b, $port_a, rtp(8, 4008, 9280, 0x6543, "\x2a" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4008, 9280, $ssrc, "\x97\x98\xc7\x16\x0a\x0e\x3a\x94\x8a\x90\xbb\x1e\x1a\x27\x56\x6f\x2f\x25\x3b\xa0\x8e\x8f\xaa\x19\x09\x0c\x28\x9c\x8f\x95\xb2\x31\x2e\x59\xcc\x37\x1b\x16\x26\xa1\x8c\x8b\x9d\x1f\x0c\x0c\x20\xab\x99\x9e\xbb\x5d\xbe\xa7\xac\x32\x13\x0d\x1a\xab\x8c\x89\x97\x2e\x10\x10\x21\xc3\xab\xbc\x4f\xd4\xa2\x96\x9c\x3f\x10\x0a\x12\xc4\x8f\x8a\x95\x57\x1b\x1a\x2b\xfd\x5d\x2d\x27\x62\x9b\x8e\x92\xc9\x12\x09\x0e\x3f\x97\x8e\x98\xc6\x2c\x2f\x6b\xd9\x2e\x1a\x18\x34\x9a\x8b\x8d\xab\x18\x0a\x0e\x2d\xa1\x98\xa1\xc7\x5b\xb9\xa7\xb4\x27\x10\x0e\x22\x9d\x8a\x8b\x9f\x20\x0e\x12\x2a\xb4\xaa\xc0\x50\xc0\x9e\x97\xa1\x2a\x0e\x0a\x19\xa8\x8c\x8b\x9b\x31\x18\x1b\x31")); +snd($sock_b, $port_a, rtp(8, 4009, 9440, 0x6543, "\x2a" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4009, 9440, $ssrc, "\xda\x50\x2c\x2b\xc0\x97\x8e\x97\x39\x0e\x09\x13\xbf\x92\x8e\x9c\x57\x29\x31\xef\x72\x28\x19\x1b\x6d\x94\x8a\x8f\xce\x11\x0a\x11\x48\x9c\x98\xa5\xdc\x5e\xb5\xa9\xc6\x1f\x0f\x10\x31\x96\x89\x8d\xad\x19\x0e\x15\x37\xac\xaa\xc8\x57\xb7\x9c\x98\xac\x1e\x0c\x0c\x21\x9c\x8b\x8d\xa4\x25\x17\x1d\x3b\xcf\x48\x2b\x30\xae\x93\x8e" . "\xff" x 80)); +# pause +snd($sock_b, $port_a, rtp(0, 4010, 9600, 0x6543, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4010, 9600, $ssrc, "\xff" x 160)); +snd($sock_b, $port_a, rtp(0, 4011, 9760, 0x6543, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4011, 9760, $ssrc, "\xff" x 160)); +snd($sock_b, $port_a, rtp(0, 4012, 9920, 0x6543, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4012, 9920, $ssrc, "\xff" x 160)); +snd($sock_b, $port_a, rtp(0, 4013, 10080, 0x6543, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4013, 10080, $ssrc, "\xff" x 160)); +snd($sock_b, $port_a, rtp(0, 4014, 10240, 0x6543, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4014, 10240, $ssrc, "\xff" x 80 . "\x00" x 80)); -answer('ICE SDP, no ICE option given', { ICE => 'optional' }, < 'force' }, < 'remove', replace => ['origin'], flags => ['inject DTMF'] }, < 'force' }, < 'remove', replace => ['origin'], flags => ['inject DTMF'] }, < 'default' }, < ft(), code => 'C', volume => 5, duration => 100 }); +$resp = rtpe_req('play DTMF', 'inject DTMF towards B', + { 'from-tag' => ft(), code => '4', volume => 5, duration => 100 }); + +snd($sock_a, $port_b, rtp(0, 1002, 3320, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1002, 3320, $ssrc, "\xff\x93\x94\xbc\x2e\x56\xbf\x2b\x13\x1b\xa7\x8e\x98\x47\x25\x41\xe2\x24\x16\x2b\x99\x8e\x9f\x28\x1e\x3d\x5b\x23\x1c\xdf\x92\x8f\xb6\x1c\x1c\x40\x5d\x26\x25\xaa\x8f\x95\x3b\x15\x1d\x5e\xde\x2c\x38\x9d\x8f\x9e\x1f\x11\x20\xc0\xc1\x37\xdd\x99\x92\xb7\x15\x10\x2c\xac\xb5\x49\xb8\x97\x99\x37\x0f\x13\x58\xa0\xae\x67\xae\x99\xa4\x1f\x0d\x1a\xae\x9b\xad\x7b\xad\x9d\xbf\x16\x0e\x27\x9d\x98\xb0\x55\xb1\xa6\x3a\x11\x11\x63\x95\x98\xbf\x3e\xbb\xb4\x26\x10\x1a\xa9\x90\x9a\x4e\x30\xce\xd4\x1e\x12\x29\x99\x8e\xa1\x2d\x29\x6d\x4b\x1c\x18\xef\x91\x8f\xb6\x1f\x24\x57\x3e\x1d\x20\xa9\x8e\x95\x3e\x19\x23\x67\x3e\x21\x31\x9c\x8e\x9e\x22\x14\x26\xcd\x4a")); +snd($sock_a, $port_b, rtp(0, 1003, 3480, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1003, 3480, $ssrc, "\x2a\xdf\x96\x90\xb5\x17\x13\x2f\xb6\xf5\x36\xb1\x93\x96\x39\x10\x15\x55\xaa\xc8\x4c\xa7\x95\xa0\x1f\x0e\x1b\xb4\xa1\xbd\xed\xa4\x99\xbb\x15\x0e\x27\xa0\x9d\xbd\xda\xa4\x9f\x39\x10\x11\x58\x98\x9c\xc8\xf9\xa9\xac\x23\x0e\x19\xab\x92\x9e\x59\x4c\xb0\xca\x1b\x10\x27\x9a\x90\xa5\x35\x3a\xbe\x43\x18\x15\x6c\x92\x91\xb7\x26\x30\xd6\x32\x18\x1d\xa9\x8e\x96\x44\x1d\x2d\xfc\x2e\x1b\x2d\x9a\x8d\x9e\x25\x19\x2d\xe7\x2f\x20\xea\x94\x8f\xb3\x19\x17\x36\xc8\x36\x2c\xae\x90\x95\x3b\x12\x18\x55\xb7\x43\x3e\xa1\x91\x9e\x1f\x0f\x1d\xba\xac\x64\xe8\x9d\x95\xb7\x15\x0e\x29\xa6\xa6\xda\xc3\x9d\x9b\x39\x0f\x11\x51\x9c\xa2\xd8\xbe\x9f\xa7\x21\x0e\x18\xad")); +snd($sock_a, $port_b, rtp(0, 1004, 3640, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1004, 3640, $ssrc, "\x96\xa3\x68\xc4\xa5\xc2\x19\x0e\x26\x9c\x93\xa9\x3f\xdb\xae\x3e\x14\x12\x5b\x93\x93\xb9\x2e\x51\xbe\x2c\x14\x1b\xa9\x8f\x97\x4c\x25\x3f\xde\x25\x16\x2a\x9a\x8e\x9e\x29\x1e\x3b\x5e\x24\x1b\x7b\x92\x8f\xb2\x1c\x1c\x3e\x61\x27\x25\xac\x8f\x94\x3e\x15\x1c\x59\xdb\x2d\x37\x9e\x8f\x9d\x20\x11\x1f\xc2\xbf\x38\xea\x99\x92\xb4\x16\x10\x2b\xad\xb4\x49\xba\x98\x98\x3a\x0f\x12\x4e\xa1\xad\x68\xaf\x99\xa3\x20\x0d\x19\xb0\x9b\xac\x7b\xae\x9d\xbc\x17\x0e\x25\x9e\x98\xaf\x55\xb2\xa6\x3d\x12\x11\x52\x96\x97\xbd\x3e\xbc\xb3\x28\x10\x19\xab\x90\x9a\x54\x2f\xd0\xcf\x1f\x12\x27\x9a\x8e\xa0\x2e\x28\x66\x4e\x1d\x18\x62\x92\x8f\xb2\x20\x23\x53\x3f\x1d\x1f")); +snd($sock_a, $port_b, rtp(0, 1005, 3800, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1005, 3800, $ssrc, "\xab\x8e\x94\x44\x19\x22\x61\x40\x21\x2f\x9c\x8e\x9d\x23\x14\x25\xce\x4d\x2a\xf7\x96\x8f\xb1\x18\x13\x2e\xb7\xe8\x36\xb3\x94\x96\x3c\x10\x15\x4d\xaa\xc5\x4b\xa8\x95\x9f\x20\x0e\x1a\xb6\xa0\xbc\xf5\xa4\x99\xb8\x16\x0e\x26\xa1\x9d\xbb\xdd\xa5\x9f\x3c\x10\x10\x4c\x99\x9b\xc5\x78\xaa\xac\x24\x0f\x18\xac\x93\x9d\x5f\x4a\xb1\xc7\x1c\x0f\x25\x9b\x90\xa3\x36\x39\xbf\x47\x18\x14\x56\x92\x90\xb4\x27\x2f\xd7\x34\x18\x1c\xab\x8e\x95\x4b\x1d\x2c\xfe\x2f\x1b\x2c\x9b\x8d\x9d\x27\x19\x2c\xe7\x30\x20\x6d\x94\x8f\xaf\x1a\x17\x34\xc8\x37\x2b\xaf\x91\x94\x3f\x12\x18\x4e\xb6\x45\x3d\xa3\x91\x9e\x20\x0f\x1c\xbc\xab\x6c\xf5\x9e\x95\xb3\x16\x0e\x27\xa7\xa5")); +snd($sock_a, $port_b, rtp(0, 1006, 3960, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1006, 3960, $ssrc, "\xd6\xc6\x9d\x9b\x3d\x0f\x11\x49\x9c\xa1\xd4\xbf\x9f\xa6\x22\x0e\x18\xaf\x96\xa2\x6e\xc6\xa5\xbe\x19\x0e\x24\x9d\x93\xa8\x40\xe1\xae\x42\x15\x12\x4e\x94\x93\xb7\x2e\x4e\xbe\x2d\x14\x1a\xab\x8f\x97\x52\x25\x3e\xdc\x26\x16\x28\x9b\x8e\x9e\x2b\x1e\x3a\x61\x25\x1b\x5d\x93\x8f\xaf\x1d\x1c\x3d\x67\x27\x24\xad\x8f\x93\x45\x15\x1c\x53\xd7\x2d\x35\x9f\x8f\x9c\x22\x11\x1f\xc5\xbe\x38\x7a\x9a\x91\xb0\x17\x10\x29\xad\xb3\x4a\xbc\x98\x98\x3e\x10\x12\x48\xa1\xad\x6a\xb1\x9a\xa1\x21\x0e\x18\xb3\x9b\xab\x7d\xaf\x9d\xb9\x18\x0e\x23\x9f\x97\xae\x55\xb4\xa5\x40\x12\x10\x49\x96\x97\xbb\x3d\xbd\xb2\x29\x10\x18\xac\x90\x99\x5d\x2f\xd4\xcd\x1f\x12\x25\x9b")); +# pause +snd($sock_a, $port_b, rtp(0, 1007, 4120, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1007, 4120, $ssrc, "\xff" x 160)); +snd($sock_a, $port_b, rtp(0, 1008, 4280, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1008, 4280, $ssrc, "\xff" x 160)); +snd($sock_a, $port_b, rtp(0, 1009, 4440, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1009, 4440, $ssrc, "\xff" x 160)); +snd($sock_a, $port_b, rtp(0, 1010, 4600, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1010, 4600, $ssrc, "\xff" x 160)); +snd($sock_a, $port_b, rtp(0, 1011, 4760, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1011, 4760, $ssrc, "\xff" x 160)); +# next event +snd($sock_a, $port_b, rtp(0, 1012, 4920, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1012, 4920, $ssrc, "\xff\x96\x8e\x99\xdd\x1f\x1d\x2c\x69\xe9\x39\x2d\x50\xa3\x95\x97\xbd\x1a\x0e\x12\x38\x9d\x93\x9b\xbf\x30\x2f\x4f\xdc\x39\x20\x1d\x33\xa2\x90\x91\xaa\x1f\x0f\x12\x2c\xa9\x9c\xa3\xc2\x55\xc9\xaf\xb8\x30\x18\x14\x24\xa7\x8f\x8e\xa0\x2a\x14\x16\x2a\xbc\xac\xbc\x61\xcf\xa8\x9d\xa6\x36\x15\x0f\x1b\xb4\x92\x8f\x9d\x3e\x1d\x1e\x31\xe0\xfe\x36\x30\xd3\x9e\x94\x9b\x50\x15\x0d\x17\xe3\x99\x93\x9e\xee\x2c\x30\x5b\xf0\x32\x1f\x1f\x4c\x9c\x8f\x94\xbe\x19\x0e\x15\x3d\xa2\x9b\xa7\xd2\x52\xc3\xaf\xc4\x29\x16\x16\x2f\x9e\x8e\x90\xac\x20\x13\x18\x34\xb2\xac\xc0\x61\xc2\xa5\x9d\xad\x29\x12\x10\x23\xa5\x8f\x90\xa5\x2d\x1b\x1f\x39\xd1\x65\x34\x36\xbb\x9b")); +snd($sock_a, $port_b, rtp(0, 1013, 5080, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1013, 5080, $ssrc, "\x94\x9f\x2f\x11\x0e\x1c\xb3\x95\x94\xa4\x45\x2a\x33\x69\x60\x2d\x1e\x23\xc7\x98\x8f\x98\x49\x15\x0e\x1a\xda\x9d\x9c\xab\x7d\x53\xbe\xb1\xe8\x22\x15\x19\x4d\x98\x8d\x94\xc3\x1b\x12\x1b\x48\xac\xac\xc7\x69\xba\xa2\x9f\xbb\x1f\x10\x12\x2f\x9c\x8e\x93\xb0\x25\x1a\x22\x44\xcb\x57\x34\x3d\xae\x99\x96\xa9\x23\x0f\x0f\x24\xa6\x93\x96\xac\x36\x29\x37\x7c\x4e\x29\x1e\x29\xb0\x94\x8f\x9e\x2d\x11\x0f\x1f\xb6\x9b\x9d\xb0\x55\x58\xbc\xb5\x49\x1e\x15\x1d\xbe\x94\x8e\x99\x45\x17\x12\x1f\xd9\xa9\xad\xce\xfa\xb3\xa0\xa2\xef\x1b\x0f\x16\x52\x97\x8e\x96\xcb\x1e\x1a\x26\x59\xc8\x4e\x35\x4d\xa8\x97\x98\xb8\x1c\x0e\x11\x31\x9d\x91\x98\xb9\x2d\x29\x3b\xf5")); +snd($sock_a, $port_b, rtp(0, 1014, 5240, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1014, 5240, $ssrc, "\x43\x27\x1f\x32\xa6\x92\x91\xa7\x21\x0f\x10\x28\xa9\x99\x9e\xba\x49\x60\xba\xbb\x38\x1b\x16\x23\xab\x90\x8e\x9e\x2d\x14\x13\x26\xbc\xa7\xaf\xd8\xde\xae\xa0\xa7\x3d\x17\x0f\x1a\xba\x93\x8e\x9b\x44\x1b\x1b\x2b\xe0\xc8\x48\x37\xe4\xa2\x96\x9b\x6f\x17\x0e\x15\x5d\x99\x91\x9c\xd7\x29\x29\x3f\xf8\x3c\x24\x21\x46\x9e\x90\x94\xb8\x1a\x0e\x14\x37\xa1\x99\xa1\xc8\x43\x76\xba\xc5\x2d\x19\x17\x2d\xa0\x8f\x8f\xa8\x21\x11\x16\x2e\xaf\xa6\xb2\xe5\xcf\xab\xa0\xad\x2d\x14\x10\x20\xa8\x90\x8f\xa1\x2e\x19\x1c\x31\xcb\xc9\x44\x3b\xc2\x9e\x96\x9f\x36\x13\x0e\x1a\xb8\x95\x92\xa0\x48\x26\x2a\x48\x73\x36\x23\x25\xd4\x9a\x90\x98\x5c\x15\x0e\x18\x72\x9c\x99")); +snd($sock_a, $port_b, rtp(0, 1015, 5400, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1015, 5400, $ssrc, "\xa6\xe8\x3f\xe7\xba\xdd\x27\x18\x1a\x43\x9a\x8e\x93\xbb\x1b\x10\x19\x3e\xaa\xa5\xb7\xf4\xc6\xa9\xa2\xba\x23\x12\x12\x2c\x9e\x8e\x91\xac\x25\x18\x1e\x3c\xc1\xcd\x41\x40\xb5\x9c\x97\xa8\x27\x10\x0f\x21\xa8\x92\x93\xa8\x35\x24\x2c\x50\x61\x30\x23\x2b\xb7\x97\x90\x9d\x31\x11\x0e\x1c\xb9\x9a\x9a\xab\x52\x3f\xd9\xbc\x54\x22\x18\x1d\xca\x96\x8e\x97\x52\x17\x10\x1c\xef\xa5\xa6\xbc\xff\xbe\xa7\xa5\xd8\x1d\x10\x16\x45\x98\x8e\x95\xbf\x1e\x17\x20\x4d\xbc\xd2\x3f\x4e\xad\x9a\x99\xb4\x1e\x0e\x10\x2d\x9e\x90\x96\xb2\x2c\x22\x2f\x5c\x54\x2d\x24\x32\xaa\x94\x91\xa5\x24\x0f\x0f\x24\xaa\x98\x9b\xb2\x43\x3f\xcf\xc0\x3e\x1e\x18\x23\xaf\x92\x8e\x9c\x2f")); +snd($sock_a, $port_b, rtp(0, 1016, 5560, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1016, 5560, $ssrc, "\x13\x11\x21\xbd\xa2\xa8\xc3\xfa\xb9\xa6\xa9\x45\x19\x10\x1a\xc2\x94\x8e\x99\x4e\x1a\x18\x26\xeb\xba\xdd\x40\x7d\xa7\x99\x9c\xda\x19\x0e\x14\x4a\x99\x90\x99\xc9\x26\x23\x34\x6d\x4b\x2b\x25\x41\xa1\x92\x94\xb3\x1c\x0e\x12\x30\xa0\x96\x9d\xbe\x3b\x41\xcc\xc9\x34\x1c\x19\x2c\xa3\x8f\x8f\xa5\x23\x10\x13\x2a\xaf\xa0\xaa\xcd\xeb\xb4\xa6\xae\x31\x16\x11\x1f\xab\x90\x8e\x9e\x30\x18\x19\x2c\xc8\xb9\xf0\x43\xcc\xa2\x99\x9f\x3c\x14\x0e\x19\xbe\x95\x90\x9d\x4e\x22\x24\x3a\xfa\x43\x2a\x28\xec\x9d\x91\x98\xe4\x16\x0d\x16\x51\x9c\x96\xa0\xd7\x37\x45\xca\xda\x2c\x1b\x1b\x3d\x9c\x8e\x92\xb4\x1c\x0f\x16\x38\xa8\xa0\xad\xda\xdd\xb0\xa7\xb9\x28\x14\x13")); +# pause +snd($sock_a, $port_b, rtp(0, 1017, 5720, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1017, 5720, $ssrc, "\xff" x 160)); +snd($sock_a, $port_b, rtp(0, 1018, 5880, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1018, 5880, $ssrc, "\xff" x 160)); +snd($sock_a, $port_b, rtp(0, 1019, 6040, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1019, 6040, $ssrc, "\xff" x 160)); +snd($sock_a, $port_b, rtp(0, 1020, 6200, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1020, 6200, $ssrc, "\xff" x 160)); +snd($sock_a, $port_b, rtp(0, 1021, 6360, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1021, 6360, $ssrc, "\xff" x 160)); +# resume +snd($sock_a, $port_b, rtp(0, 1022, 6520, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1022, 6520, $ssrc, "\x00" x 160)); + + + + +# RFC payload type present + +($sock_a, $sock_b) = new_call([qw(198.51.100.1 6010)], [qw(198.51.100.3 6012)]); + +($port_a) = offer('multi- no transcoding, RFC payload type present', + { ICE => 'remove', replace => ['origin'], flags => ['inject DTMF'] }, < 'default' }, < 'remove', replace => ['origin'], flags => ['inject DTMF'] }, < ft(), code => '0', volume => 10, duration => 100 }); +$resp = rtpe_req('play DTMF', 'inject DTMF towards B', + { 'from-tag' => ft(), code => '1', volume => 6, duration => 100 }); + +snd($sock_a, $port_b, rtp(0, 1002, 3320, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(96 | 0x80, 1002, 3320, $ssrc, "\x00\x0a\x00\xa0")); +snd($sock_a, $port_b, rtp(0, 1003, 3480, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(96, 1003, 3320, $ssrc, "\x00\x0a\x01\x40")); +snd($sock_a, $port_b, rtp(0, 1004, 3640, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(96, 1004, 3320, $ssrc, "\x00\x0a\x01\xe0")); +snd($sock_a, $port_b, rtp(0, 1005, 3800, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(96, 1005, 3320, $ssrc, "\x00\x0a\x02\x80")); +snd($sock_a, $port_b, rtp(0, 1006, 3960, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(96, 1006, 3320, $ssrc, "\x00\x0a\x03\x20")); +snd($sock_a, $port_b, rtp(0, 1007, 4120, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(96, 1007, 3320, $ssrc, "\x00\x8a\x03\xc0")); +rcv($sock_b, $port_a, rtpm(96, 1008, 3320, $ssrc, "\x00\x8a\x03\xc0")); +rcv($sock_b, $port_a, rtpm(96, 1009, 3320, $ssrc, "\x00\x8a\x03\xc0")); +snd($sock_a, $port_b, rtp(0, 1008, 4280, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1010, 4280, $ssrc, "\x00" x 160)); +snd($sock_a, $port_b, rtp(0, 1009, 4440, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1011, 4440, $ssrc, "\x00" x 160)); +snd($sock_a, $port_b, rtp(0, 1010, 4600, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1012, 4600, $ssrc, "\x00" x 160)); +snd($sock_a, $port_b, rtp(0, 1011, 4760, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1013, 4760, $ssrc, "\x00" x 160)); +snd($sock_a, $port_b, rtp(0, 1012, 4920, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(96 | 0x80, 1014, 4920, $ssrc, "\x01\x06\x00\xa0")); +snd($sock_a, $port_b, rtp(0, 1013, 5080, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(96, 1015, 4920, $ssrc, "\x01\x06\x01\x40")); +snd($sock_a, $port_b, rtp(0, 1014, 5240, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(96, 1016, 4920, $ssrc, "\x01\x06\x01\xe0")); +snd($sock_a, $port_b, rtp(0, 1015, 5400, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(96, 1017, 4920, $ssrc, "\x01\x06\x02\x80")); +snd($sock_a, $port_b, rtp(0, 1016, 5560, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(96, 1018, 4920, $ssrc, "\x01\x06\x03\x20")); +snd($sock_a, $port_b, rtp(0, 1017, 5720, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(96, 1019, 4920, $ssrc, "\x01\x86\x03\xc0")); +rcv($sock_b, $port_a, rtpm(96, 1020, 4920, $ssrc, "\x01\x86\x03\xc0")); +rcv($sock_b, $port_a, rtpm(96, 1021, 4920, $ssrc, "\x01\x86\x03\xc0")); +snd($sock_a, $port_b, rtp(0, 1018, 5880, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1022, 5880, $ssrc, "\x00" x 160)); + + + + + +# SDP in/out tests, various ICE options new_call; -offer('plain SDP, ICE default', { ICE => 'default' }, < 'remove' }, < 'remove' }, < 'force' }, < 'default' }, < 'default' }, < 'force' }, < 'optional' }, < 'remove' }, < 'remove' }, < 'remove' }, < 'optional' }, < 'remove', replace => [qw(origin session-connection)], - flags => [qw(codec-mask-opus codec-mask-G722 codec-strip-G7221)] }, < '3.4.5.6', + flags => ['full-rtcp-attribute'], ICE => 'optional', }, < 'remove', replace => [qw(origin session-connection)] }, < 'remove', replace => [qw(origin session-connection)], - flags => [qw(codec-mask-opus codec-mask-G722 codec-strip-G7221 always-transcode)] }, < 'optional' }, < 'remove', replace => [qw(origin session-connection)] }, < 'optional' }, < 'remove', replace => ['origin'] }, < 'force' }, < 'remove', replace => ['origin'] }, < 'optional' }, < 'remove', replace => ['origin'], - codec => { transcode => ['PCMA'] }}, < 'force' }, < ['origin'] }, < 'optional' }, < 'remove', replace => ['origin'], - codec => { transcode => ['PCMA'] }}, < 'force' }, < ['origin'] }, < 'force' }, < 'remove', replace => ['origin'], - codec => { transcode => ['pcma'] }}, < 'default' }, < ['origin'] }, < 'default' }, < 'remove', replace => ['origin'] }, < 'default' }, < ft(), blob => $wav_file }); -is $resp->{duration}, 100, 'media duration'; - -(undef, $seq, $ts, $ssrc) = rcv($sock_a, -1, rtpm(8 | 0x80, -1, -1, -1, $pcma_1)); -rcv($sock_a, -1, rtpm(8, $seq + 1, $ts + 160 * 1, $ssrc, $pcma_2)); -rcv($sock_a, -1, rtpm(8, $seq + 2, $ts + 160 * 2, $ssrc, $pcma_3)); -rcv($sock_a, -1, rtpm(8, $seq + 3, $ts + 160 * 3, $ssrc, $pcma_4)); -rcv($sock_a, -1, rtpm(8, $seq + 4, $ts + 160 * 4, $ssrc, $pcma_5)); - - - - -($sock_a, $sock_b) = new_call([qw(198.51.100.1 2020)], [qw(198.51.100.3 2022)]); - -offer('media playback, side A', { ICE => 'remove', replace => ['origin'] }, < ['origin'] }, < ft(), blob => $wav_file }); -is $resp->{duration}, 100, 'media duration'; - -(undef, $seq, $ts, $ssrc) = rcv($sock_a, -1, rtpm(8 | 0x80, -1, -1, -1, $pcma_1)); -rcv($sock_a, -1, rtpm(8, $seq + 1, $ts + 160 * 1, $ssrc, $pcma_2)); -rcv($sock_a, -1, rtpm(8, $seq + 2, $ts + 160 * 2, $ssrc, $pcma_3)); -rcv($sock_a, -1, rtpm(8, $seq + 3, $ts + 160 * 3, $ssrc, $pcma_4)); -rcv($sock_a, -1, rtpm(8, $seq + 4, $ts + 160 * 4, $ssrc, $pcma_5)); - - - - -($sock_a, $sock_b) = new_call([qw(198.51.100.1 2030)], [qw(198.51.100.3 2032)]); - -offer('media playback, side B', { ICE => 'remove', replace => ['origin'] }, < 'force' }, < ['origin'] }, < tt(), blob => $wav_file }); -is $resp->{duration}, 100, 'media duration'; - -(undef, $seq, $ts, $ssrc) = rcv($sock_b, -1, rtpm(8 | 0x80, -1, -1, -1, $pcma_1)); -rcv($sock_b, -1, rtpm(8, $seq + 1, $ts + 160 * 1, $ssrc, $pcma_2)); -rcv($sock_b, -1, rtpm(8, $seq + 2, $ts + 160 * 2, $ssrc, $pcma_3)); -rcv($sock_b, -1, rtpm(8, $seq + 3, $ts + 160 * 3, $ssrc, $pcma_4)); -rcv($sock_b, -1, rtpm(8, $seq + 4, $ts + 160 * 4, $ssrc, $pcma_5)); - -$resp = rtpe_req('play media', 'restart media playback', { 'from-tag' => tt(), blob => $wav_file }); -is $resp->{duration}, 100, 'media duration'; - -$ts += 160 * 5; -my $old_ts = $ts; -(undef, $ts) = rcv($sock_b, -1, rtpm(8 | 0x80, $seq + 5, -1, $ssrc, $pcma_1)); -print("ts $ts old $old_ts\n"); -SKIP: { - skip 'random timestamp too close to margin', 2 if $old_ts < 500 or $old_ts > 4294966795; - cmp_ok($ts, '<', $old_ts + 500, 'ts within < range'); - cmp_ok($ts, '>', $old_ts - 500, 'ts within > range'); -} -rcv($sock_b, -1, rtpm(8, $seq + 6, $ts + 160 * 1, $ssrc, $pcma_2)); -rcv($sock_b, -1, rtpm(8, $seq + 7, $ts + 160 * 2, $ssrc, $pcma_3)); -rcv($sock_b, -1, rtpm(8, $seq + 8, $ts + 160 * 3, $ssrc, $pcma_4)); -rcv($sock_b, -1, rtpm(8, $seq + 9, $ts + 160 * 4, $ssrc, $pcma_5)); - - - - -($sock_a, $sock_b) = new_call([qw(198.51.100.9 2020)], [qw(198.51.100.9 2022)]); +new_call; -offer('media playback, side A, select by label', { ICE => 'remove', replace => ['origin'], - label => 'foobar' }, < 'force' }, < ['origin'], label => 'blah' }, < 'foobar', - blob => $wav_file }); -is $resp->{duration}, 100, 'media duration'; - -(undef, $seq, $ts, $ssrc) = rcv($sock_a, -1, rtpm(8 | 0x80, -1, -1, -1, $pcma_1)); -rcv($sock_a, -1, rtpm(8, $seq + 1, $ts + 160 * 1, $ssrc, $pcma_2)); -rcv($sock_a, -1, rtpm(8, $seq + 2, $ts + 160 * 2, $ssrc, $pcma_3)); -rcv($sock_a, -1, rtpm(8, $seq + 3, $ts + 160 * 3, $ssrc, $pcma_4)); -rcv($sock_a, -1, rtpm(8, $seq + 4, $ts + 160 * 4, $ssrc, $pcma_5)); - - - - -($sock_a, $sock_b) = new_call([qw(198.51.100.9 2030)], [qw(198.51.100.9 2032)]); - -offer('media playback, side B, select by label', { ICE => 'remove', replace => ['origin'], - label => 'quux' }, < ['origin'], label => 'meh' }, < 'remove' }, < 'meh', blob => $wav_file }); -is $resp->{duration}, 100, 'media duration'; - -(undef, $seq, $ts, $ssrc) = rcv($sock_b, -1, rtpm(8 | 0x80, -1, -1, -1, $pcma_1)); -rcv($sock_b, -1, rtpm(8, $seq + 1, $ts + 160 * 1, $ssrc, $pcma_2)); -rcv($sock_b, -1, rtpm(8, $seq + 2, $ts + 160 * 2, $ssrc, $pcma_3)); -rcv($sock_b, -1, rtpm(8, $seq + 3, $ts + 160 * 3, $ssrc, $pcma_4)); -rcv($sock_b, -1, rtpm(8, $seq + 4, $ts + 160 * 4, $ssrc, $pcma_5)); - - - - - -# ptime tests - -($sock_a, $sock_b) = new_call([qw(198.51.100.1 3000)], [qw(198.51.100.3 3002)]); +new_call; -($port_a) = offer('default ptime in/out', { ICE => 'remove', replace => ['origin'] }, < 'remove', replace => [qw(origin session-connection)], + flags => [qw(codec-mask-opus codec-mask-G722 codec-strip-G7221)] }, < 'remove', replace => ['origin'] }, < 'remove', replace => [qw(origin session-connection)] }, < 'remove', replace => ['origin'] }, < 'remove', replace => [qw(origin session-connection)], + flags => [qw(codec-mask-opus codec-mask-G722 codec-strip-G7221 always-transcode)] }, < 'remove', replace => ['origin'] }, < 'remove', replace => [qw(origin session-connection)] }, < 'remove', replace => ['origin'], ptime => 30 }, < 'remove', replace => ['origin'] }, < 'remove', replace => ['origin'] }, < 'remove', replace => ['origin'] }, <B: 5x 20 ms packets -> 3x 30 ms snd($sock_a, $port_b, rtp(0, 1000, 3000, 0x1234, "\x00" x 160)); -Time::HiRes::usleep(20000); # 20 ms, needed to ensure that packet 1000 is received first -snd($sock_a, $port_b, rtp(0, 1001, 3160, 0x1234, "\x00" x 160)); -($ssrc) = rcv($sock_b, $port_a, rtpm(0, 1000, 3000, -1, "\x00" x 240)); -snd($sock_a, $port_b, rtp(0, 1002, 3320, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1001, 3240, $ssrc, "\x00" x 240)); -snd($sock_a, $port_b, rtp(0, 1003, 3480, 0x1234, "\x00" x 160)); -snd($sock_a, $port_b, rtp(0, 1004, 3640, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1002, 3480, $ssrc, "\x00" x 240)); - -# A->B: 60 ms packet -> 2x 30 ms -# also perform TS and seq reset -snd($sock_a, $port_b, rtp(0, 8000, 500000, 0x1234, "\x00" x 480)); -rcv($sock_b, $port_a, rtpm(0, 1003, 3720, $ssrc, "\x00" x 240)); -rcv($sock_b, $port_a, rtpm(0, 1004, 3960, $ssrc, "\x00" x 240)); - -# B->A: 2x 60 ms packet -> 6x 20 ms -snd($sock_b, $port_a, rtp(0, 4000, 5000, 0x4567, "\x88" x 480)); -($ssrc) = rcv($sock_a, $port_b, rtpm(0, 4000, 5000, -1, "\x88" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4001, 5160, $ssrc, "\x88" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4002, 5320, $ssrc, "\x88" x 160)); -snd($sock_b, $port_a, rtp(0, 4001, 5480, 0x4567, "\x88" x 480)); -rcv($sock_a, $port_b, rtpm(0, 4003, 5480, $ssrc, "\x88" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4004, 5640, $ssrc, "\x88" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4005, 5800, $ssrc, "\x88" x 160)); - -# B->A: 4x 10 ms packet -> 2x 20 ms -snd($sock_b, $port_a, rtp(0, 4002, 5960, 0x4567, "\x88" x 80)); -snd($sock_b, $port_a, rtp(0, 4003, 6040, 0x4567, "\x88" x 80)); -rcv($sock_a, $port_b, rtpm(0, 4006, 5960, $ssrc, "\x88" x 160)); -# out of order packet input -snd($sock_b, $port_a, rtp(0, 4005, 6200, 0x4567, "\x88" x 80)); -Time::HiRes::usleep(10000); -snd($sock_b, $port_a, rtp(0, 4004, 6120, 0x4567, "\x88" x 80)); -rcv($sock_a, $port_b, rtpm(0, 4007, 6120, $ssrc, "\x88" x 160)); -snd($sock_b, $port_a, rtp(0, 4006, 6280, 0x4567, "\x88" x 80)); -snd($sock_b, $port_a, rtp(0, 4007, 6360, 0x4567, "\x88" x 80)); -rcv($sock_a, $port_b, rtpm(0, 4008, 6280, $ssrc, "\x88" x 160)); - - +rcv($sock_b, $port_a, rtpm(0, 1000, 3000, 0x1234, "\x00" x 160)); +snd($sock_a, $port_b, rtp(0, 1000, 3000, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1000, 3000, 0x1234, "\x00" x 160)); +snd($sock_a, $port_b, rtp(0, 1001, 3000, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1001, 3000, 0x1234, "\x00" x 160)); +snd($sock_a, $port_b, rtp(0, 1010, 3000, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1010, 3000, 0x1234, "\x00" x 160)); +snd($sock_a, $port_b, rtp(8, 1000, 3000, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(8, 1000, 3000, 0x1234, "\x00" x 160)); +snd($sock_a, $port_b, rtp(8, 1000, 3000, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(8, 1000, 3000, 0x1234, "\x00" x 160)); +snd($sock_a, $port_b, rtp(8, 1001, 3000, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(8, 1001, 3000, 0x1234, "\x00" x 160)); +snd($sock_a, $port_b, rtp(8, 1010, 3000, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(8, 1010, 3000, 0x1234, "\x00" x 160)); -($sock_a, $sock_b) = new_call([qw(198.51.100.1 3008)], [qw(198.51.100.3 3010)]); +($sock_a, $sock_b) = new_call([qw(198.51.100.1 2010)], [qw(198.51.100.3 2012)]); -($port_a) = offer('default ptime in, no change, ptime=30 response', { - ICE => 'remove', replace => ['origin'] }, < 'remove', replace => ['origin'], + codec => { transcode => ['PCMA'] }}, < 'remove', replace => ['origin'] }, < ['origin'] }, <B: 20 ms unchanged -snd($sock_a, $port_b, rtp(0, 1000, 3000, 0x1234, "\x00" x 160)); -($ssrc) = rcv($sock_b, $port_a, rtpm(0, 1000, 3000, -1, "\x00" x 160)); -# A->B: 30 ms unchanged -snd($sock_a, $port_b, rtp(0, 1001, 3160, 0x1234, "\x00" x 240)); -rcv($sock_b, $port_a, rtpm(0, 1001, 3160, $ssrc, "\x00" x 240)); +snd($sock_a, $port_b, rtp(0, 1000, 3000, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1000, 3000, 0x1234, "\x00" x 160)); +snd($sock_a, $port_b, rtp(0, 1000, 3000, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1000, 3000, 0x1234, "\x00" x 160)); +snd($sock_a, $port_b, rtp(0, 1001, 3160, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1001, 3160, 0x1234, "\x00" x 160)); +snd($sock_a, $port_b, rtp(0, 1010, 4600, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1010, 4600, 0x1234, "\x00" x 160)); -# B->A: 20 ms unchanged -snd($sock_b, $port_a, rtp(0, 4000, 5000, 0x4567, "\x88" x 160)); -($ssrc) = rcv($sock_a, $port_b, rtpm(0, 4000, 5000, -1, "\x88" x 160)); -# B->A: 30 ms unchanged -snd($sock_b, $port_a, rtp(0, 4001, 5160, 0x4567, "\x88" x 240)); -rcv($sock_a, $port_b, rtpm(0, 4001, 5160, $ssrc, "\x88" x 240)); +snd($sock_b, $port_a, rtp(0, 2000, 4000, 0x5678, "\x00" x 160)); +($ssrc) = rcv($sock_a, $port_b, rtpm(0, 2000, 4000, -1, "\x00" x 160)); +snd($sock_b, $port_a, rtp(0, 2000, 4000, 0x5678, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 2000, 4000, $ssrc, "\x00" x 160)); +snd($sock_b, $port_a, rtp(0, 2001, 4000+160, 0x5678, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 2001, 4000+160, $ssrc, "\x00" x 160)); +snd($sock_b, $port_a, rtp(0, 2010, 4000+1600, 0x5678, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 2010, 4000+1600, $ssrc, "\x00" x 160)); + +snd($sock_b, $port_a, rtp(8, 2011, 4000+160*11, 0x5678, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 2011, 4000+160*11, $ssrc, ")" x 160)); +# #664 seq reset +snd($sock_b, $port_a, rtp(8, 62011, 4000+160*12, 0x5678, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 2012, 4000+160*12, $ssrc, ")" x 160)); +snd($sock_b, $port_a, rtp(8, 62012, 4000+160*13, 0x5678, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 2013, 4000+160*13, $ssrc, ")" x 160)); +snd($sock_b, $port_a, rtp(0, 62013, 4000+160*14, 0x5678, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 2014, 4000+160*14, $ssrc, "\x00" x 160)); -($sock_a, $sock_b) = new_call([qw(198.51.100.1 3012)], [qw(198.51.100.3 3014)]); +($sock_a, $sock_b) = new_call([qw(198.51.100.1 2210)], [qw(198.51.100.3 2212)]); -($port_a) = offer('ptime=50 in, change to 30, default response', { - ICE => 'remove', replace => ['origin'], ptime => 30 }, < 'remove', replace => ['origin'], + codec => { transcode => ['PCMA'] }}, < 'remove', replace => ['origin'] }, < ['origin'] }, <B: 2x 50 ms -> 3x 30 ms (plus 10 ms left) -snd($sock_a, $port_b, rtp(0, 1000, 3000, 0x1234, "\x00" x 400)); -($ssrc) = rcv($sock_b, $port_a, rtpm(0, 1000, 3000, -1, "\x00" x 240)); -snd($sock_a, $port_b, rtp(0, 1001, 3400, 0x1234, "\x00" x 400)); -rcv($sock_b, $port_a, rtpm(0, 1001, 3240, $ssrc, "\x00" x 240)); -rcv($sock_b, $port_a, rtpm(0, 1002, 3480, $ssrc, "\x00" x 240)); -# A->B: add another 20 ms for another full 30 ms -snd($sock_a, $port_b, rtp(0, 1002, 3800, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1003, 3720, $ssrc, "\x00" x 240)); +snd($sock_a, $port_b, rtp(0, 1000, 3000, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1000, 3000, 0x1234, "\x00" x 160)); +snd($sock_a, $port_b, rtp(0, 1000, 3000, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1000, 3000, 0x1234, "\x00" x 160)); +snd($sock_a, $port_b, rtp(0, 1001, 3160, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1001, 3160, 0x1234, "\x00" x 160)); +snd($sock_a, $port_b, rtp(0, 1010, 4600, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1010, 4600, 0x1234, "\x00" x 160)); -# B->A: 4x 30 ms -> 2x 50 ms (plus 20 ms left) -snd($sock_b, $port_a, rtp(0, 4000, 5000, 0x4567, "\x88" x 240)); -Time::HiRes::usleep(20000); # 20 ms, needed to ensure that packet 1000 is received first -snd($sock_b, $port_a, rtp(0, 4001, 5240, 0x4567, "\x88" x 240)); -($ssrc) = rcv($sock_a, $port_b, rtpm(0, 4000, 5000, -1, "\x88" x 400)); -snd($sock_b, $port_a, rtp(0, 4002, 5480, 0x4567, "\x88" x 240)); -snd($sock_b, $port_a, rtp(0, 4003, 5720, 0x4567, "\x88" x 240)); -rcv($sock_a, $port_b, rtpm(0, 4001, 5400, $ssrc, "\x88" x 400)); -# B->A: add another 30 ms for another full 50 ms -snd($sock_b, $port_a, rtp(0, 4004, 5960, 0x4567, "\x88" x 240)); -rcv($sock_a, $port_b, rtpm(0, 4002, 5800, $ssrc, "\x88" x 400)); +snd($sock_b, $port_a, rtp(0, 2000, 4000, 0x5678, "\x00" x 160)); +($ssrc) = rcv($sock_a, $port_b, rtpm(0, 2000, 4000, -1, "\x00" x 160)); +snd($sock_b, $port_a, rtp(0, 2000, 4000, 0x5678, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 2000, 4000, $ssrc, "\x00" x 160)); +snd($sock_b, $port_a, rtp(0, 2001, 4000+160, 0x5678, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 2001, 4000+160, $ssrc, "\x00" x 160)); +snd($sock_b, $port_a, rtp(0, 2010, 4000+1600, 0x5678, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 2010, 4000+1600, $ssrc, "\x00" x 160)); + +snd($sock_b, $port_a, rtp(8, 2011, 4000+160*11, 0x5678, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 2011, 4000+160*11, $ssrc, ")" x 160)); +# #664 seq reset +snd($sock_b, $port_a, rtp(8, 62011, 4000+160*12, 0x5678, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 2012, 4000+160*12, $ssrc, ")" x 160)); +snd($sock_b, $port_a, rtp(8, 62012, 4000+160*13, 0x5678, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 2013, 4000+160*13, $ssrc, ")" x 160)); +snd($sock_b, $port_a, rtp(0, 62013, 4000+160*14, 0x5678, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 2014, 4000+160*14, $ssrc, "\x00" x 160)); -($sock_a, $sock_b) = new_call([qw(198.51.100.1 3016)], [qw(198.51.100.3 3018)]); +($sock_a, $sock_b) = new_call([qw(198.51.100.1 2216)], [qw(198.51.100.3 2218)]); -($port_a) = offer('ptime=50 in, change to 30, reverse to 50, response 30', { - ICE => 'remove', replace => ['origin'], ptime => 30, 'ptime-reverse' => 50 }, < 'remove', replace => ['origin'], + codec => { transcode => ['pcma'] }}, < 'remove', replace => ['origin'] }, < ['origin'] }, <B: 2x 50 ms -> 3x 30 ms (plus 10 ms left) -snd($sock_a, $port_b, rtp(0, 1000, 3000, 0x1234, "\x00" x 400)); -($ssrc) = rcv($sock_b, $port_a, rtpm(0, 1000, 3000, -1, "\x00" x 240)); -snd($sock_a, $port_b, rtp(0, 1001, 3400, 0x1234, "\x00" x 400)); -rcv($sock_b, $port_a, rtpm(0, 1001, 3240, $ssrc, "\x00" x 240)); -rcv($sock_b, $port_a, rtpm(0, 1002, 3480, $ssrc, "\x00" x 240)); -# A->B: add another 20 ms for another full 30 ms -snd($sock_a, $port_b, rtp(0, 1002, 3800, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1003, 3720, $ssrc, "\x00" x 240)); +snd($sock_a, $port_b, rtp(0, 1000, 3000, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1000, 3000, 0x1234, "\x00" x 160)); +snd($sock_a, $port_b, rtp(0, 1000, 3000, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1000, 3000, 0x1234, "\x00" x 160)); +snd($sock_a, $port_b, rtp(0, 1001, 3160, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1001, 3160, 0x1234, "\x00" x 160)); +snd($sock_a, $port_b, rtp(0, 1010, 4600, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1010, 4600, 0x1234, "\x00" x 160)); + +snd($sock_b, $port_a, rtp(0, 2000, 4000, 0x5678, "\x00" x 160)); +($ssrc) = rcv($sock_a, $port_b, rtpm(0, 2000, 4000, -1, "\x00" x 160)); +snd($sock_b, $port_a, rtp(0, 2000, 4000, 0x5678, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 2000, 4000, $ssrc, "\x00" x 160)); +snd($sock_b, $port_a, rtp(0, 2001, 4000+160, 0x5678, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 2001, 4000+160, $ssrc, "\x00" x 160)); +snd($sock_b, $port_a, rtp(0, 2010, 4000+1600, 0x5678, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 2010, 4000+1600, $ssrc, "\x00" x 160)); + +snd($sock_b, $port_a, rtp(8, 2011, 4000+160*11, 0x5678, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 2011, 4000+160*11, $ssrc, ")" x 160)); +# #664 seq reset +snd($sock_b, $port_a, rtp(8, 62011, 4000+160*12, 0x5678, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 2012, 4000+160*12, $ssrc, ")" x 160)); +snd($sock_b, $port_a, rtp(8, 62012, 4000+160*13, 0x5678, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 2013, 4000+160*13, $ssrc, ")" x 160)); +snd($sock_b, $port_a, rtp(0, 62013, 4000+160*14, 0x5678, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 2014, 4000+160*14, $ssrc, "\x00" x 160)); -# B->A: 4x 30 ms -> 2x 50 ms (plus 20 ms left) -snd($sock_b, $port_a, rtp(0, 4000, 5000, 0x4567, "\x88" x 240)); -Time::HiRes::usleep(20000); # 20 ms, needed to ensure that packet 1000 is received first -snd($sock_b, $port_a, rtp(0, 4001, 5240, 0x4567, "\x88" x 240)); -($ssrc) = rcv($sock_a, $port_b, rtpm(0, 4000, 5000, -1, "\x88" x 400)); -snd($sock_b, $port_a, rtp(0, 4002, 5480, 0x4567, "\x88" x 240)); -snd($sock_b, $port_a, rtp(0, 4003, 5720, 0x4567, "\x88" x 240)); -rcv($sock_a, $port_b, rtpm(0, 4001, 5400, $ssrc, "\x88" x 400)); -# B->A: add another 30 ms for another full 50 ms -snd($sock_b, $port_a, rtp(0, 4004, 5960, 0x4567, "\x88" x 240)); -rcv($sock_a, $port_b, rtpm(0, 4002, 5800, $ssrc, "\x88" x 400)); -($sock_a, $sock_b) = new_call([qw(198.51.100.1 3012)], [qw(198.51.100.3 3014)]); +# media playback + +($sock_a) = new_call([qw(198.51.100.1 2020)]); -($port_a) = offer('ptime=50 in, change to 30, response 30', { - ICE => 'remove', replace => ['origin'], ptime => 30 }, < 'remove', replace => ['origin'] }, < 'remove', replace => ['origin'] }, <B: 2x 50 ms -> 3x 30 ms (plus 10 ms left) -snd($sock_a, $port_b, rtp(0, 1000, 3000, 0x1234, "\x00" x 400)); -($ssrc) = rcv($sock_b, $port_a, rtpm(0, 1000, 3000, -1, "\x00" x 240)); -snd($sock_a, $port_b, rtp(0, 1001, 3400, 0x1234, "\x00" x 400)); -rcv($sock_b, $port_a, rtpm(0, 1001, 3240, $ssrc, "\x00" x 240)); -rcv($sock_b, $port_a, rtpm(0, 1002, 3480, $ssrc, "\x00" x 240)); -# A->B: add another 20 ms for another full 30 ms -snd($sock_a, $port_b, rtp(0, 1002, 3800, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1003, 3720, $ssrc, "\x00" x 240)); +$resp = rtpe_req('play media', 'media playback, offer only', { 'from-tag' => ft(), blob => $wav_file }); +is $resp->{duration}, 100, 'media duration'; -# B->A: 4x 30 ms -> 2x 50 ms (plus 20 ms left) -snd($sock_b, $port_a, rtp(0, 4000, 5000, 0x4567, "\x88" x 240)); -Time::HiRes::usleep(20000); # 20 ms, needed to ensure that packet 1000 is received first -snd($sock_b, $port_a, rtp(0, 4001, 5240, 0x4567, "\x88" x 240)); -($ssrc) = rcv($sock_a, $port_b, rtpm(0, 4000, 5000, -1, "\x88" x 400)); -snd($sock_b, $port_a, rtp(0, 4002, 5480, 0x4567, "\x88" x 240)); -snd($sock_b, $port_a, rtp(0, 4003, 5720, 0x4567, "\x88" x 240)); -rcv($sock_a, $port_b, rtpm(0, 4001, 5400, $ssrc, "\x88" x 400)); -# B->A: add another 30 ms for another full 50 ms -snd($sock_b, $port_a, rtp(0, 4004, 5960, 0x4567, "\x88" x 240)); -rcv($sock_a, $port_b, rtpm(0, 4002, 5800, $ssrc, "\x88" x 400)); +(undef, $seq, $ts, $ssrc) = rcv($sock_a, -1, rtpm(8 | 0x80, -1, -1, -1, $pcma_1)); +rcv($sock_a, -1, rtpm(8, $seq + 1, $ts + 160 * 1, $ssrc, $pcma_2)); +rcv($sock_a, -1, rtpm(8, $seq + 2, $ts + 160 * 2, $ssrc, $pcma_3)); +rcv($sock_a, -1, rtpm(8, $seq + 3, $ts + 160 * 3, $ssrc, $pcma_4)); +rcv($sock_a, -1, rtpm(8, $seq + 4, $ts + 160 * 4, $ssrc, $pcma_5)); -($sock_a, $sock_b) = new_call([qw(198.51.100.1 3016)], [qw(198.51.100.3 3018)]); +($sock_a, $sock_b) = new_call([qw(198.51.100.1 2020)], [qw(198.51.100.3 2022)]); -($port_a) = offer('ptime=50 in, change to 30, reverse to 50, default response', { - ICE => 'remove', replace => ['origin'], ptime => 30, 'ptime-reverse' => 50 }, < 'remove', replace => ['origin'] }, < 'remove', replace => ['origin'] }, < ['origin'] }, <B: 2x 50 ms -> 3x 30 ms (plus 10 ms left) -snd($sock_a, $port_b, rtp(0, 1000, 3000, 0x1234, "\x00" x 400)); -($ssrc) = rcv($sock_b, $port_a, rtpm(0, 1000, 3000, -1, "\x00" x 240)); -snd($sock_a, $port_b, rtp(0, 1001, 3400, 0x1234, "\x00" x 400)); -rcv($sock_b, $port_a, rtpm(0, 1001, 3240, $ssrc, "\x00" x 240)); -rcv($sock_b, $port_a, rtpm(0, 1002, 3480, $ssrc, "\x00" x 240)); -# A->B: add another 20 ms for another full 30 ms -snd($sock_a, $port_b, rtp(0, 1002, 3800, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1003, 3720, $ssrc, "\x00" x 240)); -# B->A: 4x 30 ms -> 2x 50 ms (plus 20 ms left) -snd($sock_b, $port_a, rtp(0, 4000, 5000, 0x4567, "\x88" x 240)); -Time::HiRes::usleep(20000); # 20 ms, needed to ensure that packet 1000 is received first -snd($sock_b, $port_a, rtp(0, 4001, 5240, 0x4567, "\x88" x 240)); -($ssrc) = rcv($sock_a, $port_b, rtpm(0, 4000, 5000, -1, "\x88" x 400)); -snd($sock_b, $port_a, rtp(0, 4002, 5480, 0x4567, "\x88" x 240)); -snd($sock_b, $port_a, rtp(0, 4003, 5720, 0x4567, "\x88" x 240)); -rcv($sock_a, $port_b, rtpm(0, 4001, 5400, $ssrc, "\x88" x 400)); -# B->A: add another 30 ms for another full 50 ms -snd($sock_b, $port_a, rtp(0, 4004, 5960, 0x4567, "\x88" x 240)); -rcv($sock_a, $port_b, rtpm(0, 4002, 5800, $ssrc, "\x88" x 400)); +$resp = rtpe_req('play media', 'media playback, side A', { 'from-tag' => ft(), blob => $wav_file }); +is $resp->{duration}, 100, 'media duration'; + +(undef, $seq, $ts, $ssrc) = rcv($sock_a, -1, rtpm(8 | 0x80, -1, -1, -1, $pcma_1)); +rcv($sock_a, -1, rtpm(8, $seq + 1, $ts + 160 * 1, $ssrc, $pcma_2)); +rcv($sock_a, -1, rtpm(8, $seq + 2, $ts + 160 * 2, $ssrc, $pcma_3)); +rcv($sock_a, -1, rtpm(8, $seq + 3, $ts + 160 * 3, $ssrc, $pcma_4)); +rcv($sock_a, -1, rtpm(8, $seq + 4, $ts + 160 * 4, $ssrc, $pcma_5)); -($sock_a, $sock_b) = new_call([qw(198.51.100.1 3016)], [qw(198.51.100.3 3018)]); +($sock_a, $sock_b) = new_call([qw(198.51.100.1 2030)], [qw(198.51.100.3 2032)]); -($port_a) = offer('ptime=50 in, change to 30, reverse to 20, default response', { - ICE => 'remove', replace => ['origin'], ptime => 30, 'ptime-reverse' => 20 }, < 'remove', replace => ['origin'] }, < 'remove', replace => ['origin'] }, < ['origin'] }, <B: 2x 50 ms -> 3x 30 ms (plus 10 ms left) -snd($sock_a, $port_b, rtp(0, 1000, 3000, 0x1234, "\x00" x 400)); -($ssrc) = rcv($sock_b, $port_a, rtpm(0, 1000, 3000, -1, "\x00" x 240)); -snd($sock_a, $port_b, rtp(0, 1001, 3400, 0x1234, "\x00" x 400)); -rcv($sock_b, $port_a, rtpm(0, 1001, 3240, $ssrc, "\x00" x 240)); -rcv($sock_b, $port_a, rtpm(0, 1002, 3480, $ssrc, "\x00" x 240)); -# A->B: add another 20 ms for another full 30 ms -snd($sock_a, $port_b, rtp(0, 1002, 3800, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1003, 3720, $ssrc, "\x00" x 240)); -# B->A: 4x 30 ms -> 6x 20 ms -snd($sock_b, $port_a, rtp(0, 4000, 5000, 0x4567, "\x88" x 240)); -($ssrc) = rcv($sock_a, $port_b, rtpm(0, 4000, 5000, -1, "\x88" x 160)); -snd($sock_b, $port_a, rtp(0, 4001, 5240, 0x4567, "\x88" x 240)); -rcv($sock_a, $port_b, rtpm(0, 4001, 5160, $ssrc, "\x88" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4002, 5320, $ssrc, "\x88" x 160)); -snd($sock_b, $port_a, rtp(0, 4002, 5480, 0x4567, "\x88" x 240)); -rcv($sock_a, $port_b, rtpm(0, 4003, 5480, $ssrc, "\x88" x 160)); -snd($sock_b, $port_a, rtp(0, 4003, 5720, 0x4567, "\x88" x 240)); -rcv($sock_a, $port_b, rtpm(0, 4004, 5640, $ssrc, "\x88" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4005, 5800, $ssrc, "\x88" x 160)); +$resp = rtpe_req('play media', 'media playback, side B', { 'from-tag' => tt(), blob => $wav_file }); +is $resp->{duration}, 100, 'media duration'; +(undef, $seq, $ts, $ssrc) = rcv($sock_b, -1, rtpm(8 | 0x80, -1, -1, -1, $pcma_1)); +rcv($sock_b, -1, rtpm(8, $seq + 1, $ts + 160 * 1, $ssrc, $pcma_2)); +rcv($sock_b, -1, rtpm(8, $seq + 2, $ts + 160 * 2, $ssrc, $pcma_3)); +rcv($sock_b, -1, rtpm(8, $seq + 3, $ts + 160 * 3, $ssrc, $pcma_4)); +rcv($sock_b, -1, rtpm(8, $seq + 4, $ts + 160 * 4, $ssrc, $pcma_5)); + +$resp = rtpe_req('play media', 'restart media playback', { 'from-tag' => tt(), blob => $wav_file }); +is $resp->{duration}, 100, 'media duration'; + +$ts += 160 * 5; +my $old_ts = $ts; +(undef, $ts) = rcv($sock_b, -1, rtpm(8 | 0x80, $seq + 5, -1, $ssrc, $pcma_1)); +print("ts $ts old $old_ts\n"); +SKIP: { + skip 'random timestamp too close to margin', 2 if $old_ts < 500 or $old_ts > 4294966795; + cmp_ok($ts, '<', $old_ts + 500, 'ts within < range'); + cmp_ok($ts, '>', $old_ts - 500, 'ts within > range'); +} +rcv($sock_b, -1, rtpm(8, $seq + 6, $ts + 160 * 1, $ssrc, $pcma_2)); +rcv($sock_b, -1, rtpm(8, $seq + 7, $ts + 160 * 2, $ssrc, $pcma_3)); +rcv($sock_b, -1, rtpm(8, $seq + 8, $ts + 160 * 3, $ssrc, $pcma_4)); +rcv($sock_b, -1, rtpm(8, $seq + 9, $ts + 160 * 4, $ssrc, $pcma_5)); -($sock_a, $sock_b) = new_call([qw(198.51.100.1 3016)], [qw(198.51.100.3 3018)]); -($port_a) = offer('ptime=50 in, change to 30, reverse to 20, response 40', { - ICE => 'remove', replace => ['origin'], ptime => 30, 'ptime-reverse' => 20 }, < 'remove', replace => ['origin'], + label => 'foobar' }, < 'remove', replace => ['origin'] }, < ['origin'], label => 'blah' }, <B: 2x 50 ms -> 3x 30 ms (plus 10 ms left) -snd($sock_a, $port_b, rtp(0, 1000, 3000, 0x1234, "\x00" x 400)); -($ssrc) = rcv($sock_b, $port_a, rtpm(0, 1000, 3000, -1, "\x00" x 240)); -snd($sock_a, $port_b, rtp(0, 1001, 3400, 0x1234, "\x00" x 400)); -rcv($sock_b, $port_a, rtpm(0, 1001, 3240, $ssrc, "\x00" x 240)); -rcv($sock_b, $port_a, rtpm(0, 1002, 3480, $ssrc, "\x00" x 240)); -# A->B: add another 20 ms for another full 30 ms -snd($sock_a, $port_b, rtp(0, 1002, 3800, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1003, 3720, $ssrc, "\x00" x 240)); -# B->A: 4x 30 ms -> 6x 20 ms -snd($sock_b, $port_a, rtp(0, 4000, 5000, 0x4567, "\x88" x 240)); -($ssrc) = rcv($sock_a, $port_b, rtpm(0, 4000, 5000, -1, "\x88" x 160)); -snd($sock_b, $port_a, rtp(0, 4001, 5240, 0x4567, "\x88" x 240)); -rcv($sock_a, $port_b, rtpm(0, 4001, 5160, $ssrc, "\x88" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4002, 5320, $ssrc, "\x88" x 160)); -snd($sock_b, $port_a, rtp(0, 4002, 5480, 0x4567, "\x88" x 240)); -rcv($sock_a, $port_b, rtpm(0, 4003, 5480, $ssrc, "\x88" x 160)); -snd($sock_b, $port_a, rtp(0, 4003, 5720, 0x4567, "\x88" x 240)); -rcv($sock_a, $port_b, rtpm(0, 4004, 5640, $ssrc, "\x88" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4005, 5800, $ssrc, "\x88" x 160)); +$resp = rtpe_req('play media', 'media playback, side A, select by label', { label => 'foobar', + blob => $wav_file }); +is $resp->{duration}, 100, 'media duration'; + +(undef, $seq, $ts, $ssrc) = rcv($sock_a, -1, rtpm(8 | 0x80, -1, -1, -1, $pcma_1)); +rcv($sock_a, -1, rtpm(8, $seq + 1, $ts + 160 * 1, $ssrc, $pcma_2)); +rcv($sock_a, -1, rtpm(8, $seq + 2, $ts + 160 * 2, $ssrc, $pcma_3)); +rcv($sock_a, -1, rtpm(8, $seq + 3, $ts + 160 * 3, $ssrc, $pcma_4)); +rcv($sock_a, -1, rtpm(8, $seq + 4, $ts + 160 * 4, $ssrc, $pcma_5)); -($sock_a, $sock_b) = new_call([qw(198.51.100.1 3016)], [qw(198.51.100.3 3018)]); +($sock_a, $sock_b) = new_call([qw(198.51.100.9 2030)], [qw(198.51.100.9 2032)]); -($port_a) = offer('ptime=30 in, no change, reverse to 20, response 40', { - ICE => 'remove', replace => ['origin'], 'ptime-reverse' => 20 }, < 'remove', replace => ['origin'], + label => 'quux' }, < 'remove', replace => ['origin'] }, < ['origin'], label => 'meh' }, <B: 2x 50 ms -> 3x 30 ms (plus 10 ms left) -snd($sock_a, $port_b, rtp(0, 1000, 3000, 0x1234, "\x00" x 400)); -($ssrc) = rcv($sock_b, $port_a, rtpm(0, 1000, 3000, -1, "\x00" x 240)); -snd($sock_a, $port_b, rtp(0, 1001, 3400, 0x1234, "\x00" x 400)); -rcv($sock_b, $port_a, rtpm(0, 1001, 3240, $ssrc, "\x00" x 240)); -rcv($sock_b, $port_a, rtpm(0, 1002, 3480, $ssrc, "\x00" x 240)); -# A->B: add another 20 ms for another full 30 ms -snd($sock_a, $port_b, rtp(0, 1002, 3800, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1003, 3720, $ssrc, "\x00" x 240)); -# B->A: 4x 30 ms -> 6x 20 ms -snd($sock_b, $port_a, rtp(0, 4000, 5000, 0x4567, "\x88" x 240)); -($ssrc) = rcv($sock_a, $port_b, rtpm(0, 4000, 5000, -1, "\x88" x 160)); -snd($sock_b, $port_a, rtp(0, 4001, 5240, 0x4567, "\x88" x 240)); -rcv($sock_a, $port_b, rtpm(0, 4001, 5160, $ssrc, "\x88" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4002, 5320, $ssrc, "\x88" x 160)); -snd($sock_b, $port_a, rtp(0, 4002, 5480, 0x4567, "\x88" x 240)); -rcv($sock_a, $port_b, rtpm(0, 4003, 5480, $ssrc, "\x88" x 160)); -snd($sock_b, $port_a, rtp(0, 4003, 5720, 0x4567, "\x88" x 240)); -rcv($sock_a, $port_b, rtpm(0, 4004, 5640, $ssrc, "\x88" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4005, 5800, $ssrc, "\x88" x 160)); +$resp = rtpe_req('play media', 'media playback, side B, select by label', { label => 'meh', blob => $wav_file }); +is $resp->{duration}, 100, 'media duration'; + +(undef, $seq, $ts, $ssrc) = rcv($sock_b, -1, rtpm(8 | 0x80, -1, -1, -1, $pcma_1)); +rcv($sock_b, -1, rtpm(8, $seq + 1, $ts + 160 * 1, $ssrc, $pcma_2)); +rcv($sock_b, -1, rtpm(8, $seq + 2, $ts + 160 * 2, $ssrc, $pcma_3)); +rcv($sock_b, -1, rtpm(8, $seq + 3, $ts + 160 * 3, $ssrc, $pcma_4)); +rcv($sock_b, -1, rtpm(8, $seq + 4, $ts + 160 * 4, $ssrc, $pcma_5)); + diff --git a/t/auto-daemon-tests.pl b/t/auto-daemon-tests.pl index 598ee63df..7c518e7e6 100755 --- a/t/auto-daemon-tests.pl +++ b/t/auto-daemon-tests.pl @@ -2535,7 +2535,7 @@ snd($sock_b, $port_a, rtp(8, 1001, 3160, 0x1234, "\x00" x 160)); ($ssrc) = rcv($sock_a, $port_b, rtpm(96, 1000, 3000, -1, "\xf0\x44\xd0\x46\x0d\x8d\xd6\xf3\x02\x71\x71\xf0\x00\x00\x0a\x16\x87\x77\x22\x31\xc8\x21\x00\x8b\xe8\x45\xf2\x94\x41\xd6\xf7\xd1\x68\xb1\xed\x39\x5f\x37\xbe\xbc\xd6\x47\x89\xc4\x14\xad\xff\x1b\x69\xe7\x72\x80\x44\xc4\x97\x2f\x9f\xc7\xc4\xa8\x94\xc0")); # control for CMR test below: snd($sock_b, $port_a, rtp(8, 1002, 3320, 0x1234, "\x00" x 160)); -rcv($sock_a, $port_b, rtpm(96, 1001, 3240, $ssrc, "\xf0\x44\xe0\x94\x24\x91\xd6\x45\x0d\x23\xdf\x00\x01\xad\xc9\x47\xc5\x2f\xf7\xfb\x62\x39\x06\xaf\x4d\x1c\x1e\x02\x6d\x94\xd1\x98\x28\x16\x25\x11\x1f\x56\xaa\x25\x40\x79\x19\x7e\x98\x8b\xbf\x78\x24\xe4\x37\x80\xad\x54\x59\x6d\xfd\x74\xcc\x40\x3f\x10")); +rcv($sock_a, $port_b, rtpm(96, 1001, 3320, $ssrc, "\xf0\x44\xe0\x94\x24\x91\xd6\x45\x0d\x23\xdf\x00\x01\xad\xc9\x47\xc5\x2f\xf7\xfb\x62\x39\x06\xaf\x4d\x1c\x1e\x02\x6d\x94\xd1\x98\x28\x16\x25\x11\x1f\x56\xaa\x25\x40\x79\x19\x7e\x98\x8b\xbf\x78\x24\xe4\x37\x80\xad\x54\x59\x6d\xfd\x74\xcc\x40\x3f\x10")); @@ -2655,10 +2655,10 @@ snd($sock_a, $port_b, rtp(96, 2000, 4000, 0x5678, "\x10\x04\x89\xf1\xd9\x1c\xd6\ Time::HiRes::usleep(20000); # 20 ms, wait to be processed snd($sock_b, $port_a, rtp(8, 1002, 3320, 0x1234, "\x00" x 160)); # receive one more mode 8 frame, then CMR kicks in -rcv($sock_a, $port_b, rtpm(96, 1001, 3240, $ssrc, "\xf0\x44\xe0\x94\x24\x91\xd6\x45\x0d\x23\xdf\x00\x01\xad\xc9\x47\xc5\x2f\xf7\xfb\x62\x39\x06\xaf\x4d\x1c\x1e\x02\x6d\x94\xd1\x98\x28\x16\x25\x11\x1f\x56\xaa\x25\x40\x79\x19\x7e\x98\x8b\xbf\x78\x24\xe4\x37\x80\xad\x54\x59\x6d\xfd\x74\xcc\x40\x3f\x10")); +rcv($sock_a, $port_b, rtpm(96, 1001, 3320, $ssrc, "\xf0\x44\xe0\x94\x24\x91\xd6\x45\x0d\x23\xdf\x00\x01\xad\xc9\x47\xc5\x2f\xf7\xfb\x62\x39\x06\xaf\x4d\x1c\x1e\x02\x6d\x94\xd1\x98\x28\x16\x25\x11\x1f\x56\xaa\x25\x40\x79\x19\x7e\x98\x8b\xbf\x78\x24\xe4\x37\x80\xad\x54\x59\x6d\xfd\x74\xcc\x40\x3f\x10")); snd($sock_b, $port_a, rtp(8, 1003, 3480, 0x1234, "\x00" x 160)); # now mode 1 -rcv($sock_a, $port_b, rtpm(96, 1002, 3560, $ssrc, "\xf0\x0c\x54\x01\x1e\x01\x14\x6c\xb0\x53\xa3\x87\x8d\x76\x75\xd0\x30\x76\x70\x10\x24\x6a\x10\x62\x00")); +rcv($sock_a, $port_b, rtpm(96, 1002, 3640, $ssrc, "\xf0\x0c\x54\x01\x1e\x01\x14\x6c\xb0\x53\xa3\x87\x8d\x76\x75\xd0\x30\x76\x70\x10\x24\x6a\x10\x62\x00")); @@ -2722,16 +2722,16 @@ snd($sock_a, $port_b, rtp(96, 2000, 4000, 0x5678, "\x00\x04\x89\xf1\xd9\x1c\xd6\ Time::HiRes::usleep(20000); # 20 ms, wait to be processed snd($sock_b, $port_a, rtp(8, 1002, 3320, 0x1234, "\x00" x 160)); # recv one more frame with mode 6 before CMR kicks in -rcv($sock_a, $port_b, rtpm(96, 1001, 3240, $ssrc, "\xf0\x34\xe2\x98\x10\xea\xff\xc9\x7d\x23\xdf\x6d\xd9\x47\xd5\x41\xbe\x02\xa2\xd8\xb6\x5a\x18\xfa\x62\x01\xd6\x1c\x5f\x1a\xe6\xef\x1d\x23\xd0\xf5\x3c\x05\xd1\xbd\x4e\x9b\xd5\xc3\x9b\x49\x2b\x19\x41\x0c\x60\x80")); +rcv($sock_a, $port_b, rtpm(96, 1001, 3320, $ssrc, "\xf0\x34\xe2\x98\x10\xea\xff\xc9\x7d\x23\xdf\x6d\xd9\x47\xd5\x41\xbe\x02\xa2\xd8\xb6\x5a\x18\xfa\x62\x01\xd6\x1c\x5f\x1a\xe6\xef\x1d\x23\xd0\xf5\x3c\x05\xd1\xbd\x4e\x9b\xd5\xc3\x9b\x49\x2b\x19\x41\x0c\x60\x80")); snd($sock_b, $port_a, rtp(8, 1003, 3480, 0x1234, "\x00" x 160)); # recv mode 4 -rcv($sock_a, $port_b, rtpm(96, 1002, 3560, $ssrc, "\xf0\x24\x41\x44\x30\x11\x12\x46\x3c\xb0\x53\x25\x8f\x8d\x46\x5c\x7d\xc7\xc2\x7b\x06\xb4\xd9\x48\x41\x74\xa1\x06\x04\x1c\xd2\x94\x09\x4e\x6c\x1c\x20\xbc\x98\x47\x47\x28")); +rcv($sock_a, $port_b, rtpm(96, 1002, 3640, $ssrc, "\xf0\x24\x41\x44\x30\x11\x12\x46\x3c\xb0\x53\x25\x8f\x8d\x46\x5c\x7d\xc7\xc2\x7b\x06\xb4\xd9\x48\x41\x74\xa1\x06\x04\x1c\xd2\x94\x09\x4e\x6c\x1c\x20\xbc\x98\x47\x47\x28")); snd($sock_b, $port_a, rtp(8, 1004, 3640, 0x1234, "\x00" x 160)); # recv mode 2 -rcv($sock_a, $port_b, rtpm(96, 1003, 3880, $ssrc, "\xf0\x14\x41\x46\x30\x77\x75\xde\x11\x15\x55\x79\x8a\x06\x44\xc0\x70\x7f\x07\x85\x81\x87\x86\xb7\xa5\xa5\x18\x33\x35\x39\x98\xa0\x4c\x20")); +rcv($sock_a, $port_b, rtpm(96, 1003, 3960, $ssrc, "\xf0\x14\x41\x46\x30\x77\x75\xde\x11\x15\x55\x79\x8a\x06\x44\xc0\x70\x7f\x07\x85\x81\x87\x86\xb7\xa5\xa5\x18\x33\x35\x39\x98\xa0\x4c\x20")); snd($sock_b, $port_a, rtp(8, 1005, 3800, 0x1234, "\x00" x 160)); # recv mode 0 -rcv($sock_a, $port_b, rtpm(96, 1004, 4200, $ssrc, "\xf0\x04\x30\x01\x00\x28\x1c\x10\x30\x0b\x02\x07\x8b\x00\x84\x00\xc4\x80\x00")); +rcv($sock_a, $port_b, rtpm(96, 1004, 4280, $ssrc, "\xf0\x04\x30\x01\x00\x28\x1c\x10\x30\x0b\x02\x07\x8b\x00\x84\x00\xc4\x80\x00")); @@ -2798,34 +2798,34 @@ snd($sock_a, $port_b, rtp(96, 2000, 4000, 0x5678, "\x70\x04\x89\xf1\xd9\x1c\xd6\ Time::HiRes::usleep(20000); # 20 ms, wait to be processed snd($sock_b, $port_a, rtp(8, 1002, 3320, 0x1234, "\x00" x 160)); # recv one more frame with mode 0 before CMR kicks in -rcv($sock_a, $port_b, rtpm(96, 1001, 3240, $ssrc, "\xf0\x04\xe0\x34\x00\x39\x83\x38\x90\x82\xd2\xc2\xca\x8c\x8c\x03\x18\x8b\x90")); +rcv($sock_a, $port_b, rtpm(96, 1001, 3320, $ssrc, "\xf0\x04\xe0\x34\x00\x39\x83\x38\x90\x82\xd2\xc2\xca\x8c\x8c\x03\x18\x8b\x90")); snd($sock_b, $port_a, rtp(8, 1003, 3480, 0x1234, "\x00" x 160)); # mode change suppressed due to period=2, so one more mode 0 -rcv($sock_a, $port_b, rtpm(96, 1002, 3560, $ssrc, "\xf0\x04\x10\x31\x00\x38\x9c\x7c\xb6\x01\x72\x05\x1b\xd2\xd6\x84\x34\x76\x00")); +rcv($sock_a, $port_b, rtpm(96, 1002, 3640, $ssrc, "\xf0\x04\x10\x31\x00\x38\x9c\x7c\xb6\x01\x72\x05\x1b\xd2\xd6\x84\x34\x76\x00")); snd($sock_b, $port_a, rtp(8, 1004, 3640, 0x1234, "\x00" x 160)); # recv mode 1 -rcv($sock_a, $port_b, rtpm(96, 1003, 3880, $ssrc, "\xf0\x0c\x54\x00\x0f\x00\x0e\x31\x15\x77\xf7\x8a\x96\x3a\x97\x07\x80\x42\x02\x72\x0a\x24\xa4\x4c\x00")); +rcv($sock_a, $port_b, rtpm(96, 1003, 3960, $ssrc, "\xf0\x0c\x54\x00\x0f\x00\x0e\x31\x15\x77\xf7\x8a\x96\x3a\x97\x07\x80\x42\x02\x72\x0a\x24\xa4\x4c\x00")); snd($sock_b, $port_a, rtp(8, 1005, 3800, 0x1234, "\x00" x 160)); # recv mode 1 -rcv($sock_a, $port_b, rtpm(96, 1004, 4200, $ssrc, "\xf0\x0c\x14\x00\x0f\x00\x0e\x08\x44\x91\x16\x79\xf6\xde\x12\xcd\x81\x28\x02\x64\x3b\x64\x29\x5e\x80")); +rcv($sock_a, $port_b, rtpm(96, 1004, 4280, $ssrc, "\xf0\x0c\x14\x00\x0f\x00\x0e\x08\x44\x91\x16\x79\xf6\xde\x12\xcd\x81\x28\x02\x64\x3b\x64\x29\x5e\x80")); snd($sock_b, $port_a, rtp(8, 1006, 3960, 0x1234, "\x00" x 160)); # recv mode 3 -rcv($sock_a, $port_b, rtpm(96, 1005, 4520, $ssrc, "\xf0\x1c\x01\x44\x00\x22\x2c\x88\xe8\x41\x94\xa0\x09\x82\xb2\xc5\x23\xfa\x5d\x5e\x33\xb1\x41\xfd\x04\x52\x55\x51\x4b\x15\x31\x38\x55\x00\x59\xd5\x98\x80")); +rcv($sock_a, $port_b, rtpm(96, 1005, 4600, $ssrc, "\xf0\x1c\x01\x44\x00\x22\x2c\x88\xe8\x41\x94\xa0\x09\x82\xb2\xc5\x23\xfa\x5d\x5e\x33\xb1\x41\xfd\x04\x52\x55\x51\x4b\x15\x31\x38\x55\x00\x59\xd5\x98\x80")); snd($sock_b, $port_a, rtp(8, 1007, 4120, 0x1234, "\x00" x 160)); # recv mode 3 -rcv($sock_a, $port_b, rtpm(96, 1006, 4840, $ssrc, "\xf0\x1c\x41\x06\x00\xee\xe3\xb8\x4d\x80\x61\xa6\x48\xc2\x92\x80\x33\x37\xdf\x3e\x81\x76\xf2\x60\x4f\x4a\x24\x45\x01\x34\xc3\x32\x20\x67\x3b\x30\x67\x48")); +rcv($sock_a, $port_b, rtpm(96, 1006, 4920, $ssrc, "\xf0\x1c\x41\x06\x00\xee\xe3\xb8\x4d\x80\x61\xa6\x48\xc2\x92\x80\x33\x37\xdf\x3e\x81\x76\xf2\x60\x4f\x4a\x24\x45\x01\x34\xc3\x32\x20\x67\x3b\x30\x67\x48")); snd($sock_b, $port_a, rtp(8, 1008, 4280, 0x1234, "\x00" x 160)); # recv mode 6 -rcv($sock_a, $port_b, rtpm(96, 1007, 5160, $ssrc, "\xf0\x34\x01\x46\x00\xee\xeb\xb8\x29\xc0\xd7\xe6\x69\xfa\xb2\xdf\xc3\x3a\xfa\xa1\xa3\x10\x81\xd9\x7b\xd5\x60\x11\x82\x03\x18\x87\x41\x49\xb6\x62\x3b\x79\x44\x50\x46\x3a\xfb\x1c\x00\x07\x16\x92\x8c\x95\x81\x00")); +rcv($sock_a, $port_b, rtpm(96, 1007, 5240, $ssrc, "\xf0\x34\x01\x46\x00\xee\xeb\xb8\x29\xc0\xd7\xe6\x69\xfa\xb2\xdf\xc3\x3a\xfa\xa1\xa3\x10\x81\xd9\x7b\xd5\x60\x11\x82\x03\x18\x87\x41\x49\xb6\x62\x3b\x79\x44\x50\x46\x3a\xfb\x1c\x00\x07\x16\x92\x8c\x95\x81\x00")); snd($sock_b, $port_a, rtp(8, 1009, 4440, 0x1234, "\x00" x 160)); # recv mode 6 -rcv($sock_a, $port_b, rtpm(96, 1008, 5480, $ssrc, "\xf0\x34\x41\x44\x10\xff\xff\xfc\x40\xc1\x24\xa2\x0c\xca\xb2\xbf\x43\x02\xbc\x90\x01\x2a\xe1\xcd\x71\x1d\x02\x41\xa6\x37\xbd\xc5\x95\xd7\x98\x44\x12\x61\xcc\x62\x41\xd6\x22\x36\x4c\x82\x14\x66\x08\x8d\x0b\x70")); +rcv($sock_a, $port_b, rtpm(96, 1008, 5560, $ssrc, "\xf0\x34\x41\x44\x10\xff\xff\xfc\x40\xc1\x24\xa2\x0c\xca\xb2\xbf\x43\x02\xbc\x90\x01\x2a\xe1\xcd\x71\x1d\x02\x41\xa6\x37\xbd\xc5\x95\xd7\x98\x44\x12\x61\xcc\x62\x41\xd6\x22\x36\x4c\x82\x14\x66\x08\x8d\x0b\x70")); snd($sock_b, $port_a, rtp(8, 1010, 4600, 0x1234, "\x00" x 160)); # recv mode 7 -rcv($sock_a, $port_b, rtpm(96, 1009, 5800, $ssrc, "\xf0\x3c\x01\x46\x30\xee\xeb\xb8\x19\xc0\xd5\xe6\xf9\xea\x92\xda\xd6\x5b\x4b\x2f\x83\x13\x60\x2e\x1a\xdc\xae\x8c\x44\x31\x81\x95\x6b\x19\x21\x54\xc6\x2c\x41\x9f\x90\xf1\x46\xc9\x8d\x10\xaa\xdf\x70\x0d\x71\x07\x09\x1b\x32\x0d\x3c\x2a\x01\x10")); +rcv($sock_a, $port_b, rtpm(96, 1009, 5880, $ssrc, "\xf0\x3c\x01\x46\x30\xee\xeb\xb8\x19\xc0\xd5\xe6\xf9\xea\x92\xda\xd6\x5b\x4b\x2f\x83\x13\x60\x2e\x1a\xdc\xae\x8c\x44\x31\x81\x95\x6b\x19\x21\x54\xc6\x2c\x41\x9f\x90\xf1\x46\xc9\x8d\x10\xaa\xdf\x70\x0d\x71\x07\x09\x1b\x32\x0d\x3c\x2a\x01\x10")); snd($sock_b, $port_a, rtp(8, 1011, 4760, 0x1234, "\x00" x 160)); # recv mode 7 -rcv($sock_a, $port_b, rtpm(96, 1010, 6120, $ssrc, "\xf0\x3c\x41\x46\x00\xee\xef\xb8\x60\xc1\x22\xe5\x14\xc2\xa2\xe8\xb4\xc1\x42\x09\x12\x0a\x08\xb6\x86\xd4\x78\xaf\x57\xc1\xa0\x94\x6d\x5c\x29\xd8\xf6\x88\x90\xba\xaf\x7d\xd2\x60\x94\x0e\xd0\x20\x4e\x2f\xcf\x02\x0b\x9b\x10\xe8\x10\xec\x05\xd8")); +rcv($sock_a, $port_b, rtpm(96, 1010, 6200, $ssrc, "\xf0\x3c\x41\x46\x00\xee\xef\xb8\x60\xc1\x22\xe5\x14\xc2\xa2\xe8\xb4\xc1\x42\x09\x12\x0a\x08\xb6\x86\xd4\x78\xaf\x57\xc1\xa0\x94\x6d\x5c\x29\xd8\xf6\x88\x90\xba\xaf\x7d\xd2\x60\x94\x0e\xd0\x20\x4e\x2f\xcf\x02\x0b\x9b\x10\xe8\x10\xec\x05\xd8")); @@ -2900,12 +2900,12 @@ snd($sock_b, $port_a, rtp(8, 1001, 3160, 0x1234, "\x00" x 160)); # receive 3 packets with CMRs ($ssrc) = rcv($sock_a, $port_b, rtpm(96, 1000, 3000, -1, "\x40\x1c\xd0\x46\x09\xa1\xf1\x73\x02\x71\x71\x00\x0a\x16\x87\x74\xea\x6a\x8c\x06\x67\x66\xec\xf5\x67\x6c\x54\x6d\x45\x4c\x7c\x59\x8d\x7c\x55\xc4\x6c\x50")); snd($sock_b, $port_a, rtp(8, 1002, 3320, 0x1234, "\x00" x 160)); -rcv($sock_a, $port_b, rtpm(96, 1001, 3240, $ssrc, "\x40\x1c\xe0\x92\x30\xf3\xf4\xff\x3d\x23\xdb\x6b\x59\x4f\xd5\x12\xad\xff\x5b\xf8\x88\x53\x85\x74\x19\x6d\x65\x63\x6e\x94\xbb\x5b\x9f\x7d\x97\x3c\x28\xe8")); +rcv($sock_a, $port_b, rtpm(96, 1001, 3320, $ssrc, "\x40\x1c\xe0\x92\x30\xf3\xf4\xff\x3d\x23\xdb\x6b\x59\x4f\xd5\x12\xad\xff\x5b\xf8\x88\x53\x85\x74\x19\x6d\x65\x63\x6e\x94\xbb\x5b\x9f\x7d\x97\x3c\x28\xe8")); snd($sock_b, $port_a, rtp(8, 1003, 3480, 0x1234, "\x00" x 160)); -rcv($sock_a, $port_b, rtpm(96, 1002, 3560, $ssrc, "\x40\x1c\x41\x42\x00\xd9\xd7\x64\x3c\xb0\x51\xe7\x1f\x95\x56\x3b\x34\x76\x35\x73\x46\x32\x16\x72\x67\xc4\x54\x16\x02\x64\x30\x36\x34\x18\xba\x14\xce\xd8")); +rcv($sock_a, $port_b, rtpm(96, 1002, 3640, $ssrc, "\x40\x1c\x41\x42\x00\xd9\xd7\x64\x3c\xb0\x51\xe7\x1f\x95\x56\x3b\x34\x76\x35\x73\x46\x32\x16\x72\x67\xc4\x54\x16\x02\x64\x30\x36\x34\x18\xba\x14\xce\xd8")); snd($sock_b, $port_a, rtp(8, 1004, 3640, 0x1234, "\x00" x 160)); # back to no CMR -rcv($sock_a, $port_b, rtpm(96, 1003, 3880, $ssrc, "\xf0\x1c\x41\x46\x30\xff\xf7\xfc\x31\x15\x57\x3b\x0a\x1e\x44\xcd\x5e\x0e\xa7\xe4\x3a\x1b\xb5\x7b\x38\x2a\x90\x13\x08\xf3\x5f\xaa\xba\x57\xb0\x30\xd3\xe8")); +rcv($sock_a, $port_b, rtpm(96, 1003, 3960, $ssrc, "\xf0\x1c\x41\x46\x30\xff\xf7\xfc\x31\x15\x57\x3b\x0a\x1e\x44\xcd\x5e\x0e\xa7\xe4\x3a\x1b\xb5\x7b\x38\x2a\x90\x13\x08\xf3\x5f\xaa\xba\x57\xb0\x30\xd3\xe8")); @@ -2969,10 +2969,10 @@ snd($sock_a, $port_b, rtp(96, 2000, 4000, 0x5678, "\x10\x1c\xd0\x46\x09\xa1\xf1\ Time::HiRes::usleep(20000); # 20 ms, wait to be processed snd($sock_b, $port_a, rtp(8, 1002, 3320, 0x1234, "\x00" x 160)); # receive one more mode 8 frame, then CMR kicks in -rcv($sock_a, $port_b, rtpm(96, 1001, 3240, $ssrc, "\xf0\x44\xe0\x94\x24\x91\xd6\x45\x0d\x23\xdf\x00\x01\xad\xc9\x47\xc5\x2f\xf7\xfb\x62\x39\x06\xaf\x4d\x1c\x1e\x02\x6d\x94\xd1\x98\x28\x16\x25\x11\x1f\x56\xaa\x25\x40\x79\x19\x7e\x98\x8b\xbf\x78\x24\xe4\x37\x80\xad\x54\x59\x6d\xfd\x74\xcc\x40\x3f\x10")); +rcv($sock_a, $port_b, rtpm(96, 1001, 3320, $ssrc, "\xf0\x44\xe0\x94\x24\x91\xd6\x45\x0d\x23\xdf\x00\x01\xad\xc9\x47\xc5\x2f\xf7\xfb\x62\x39\x06\xaf\x4d\x1c\x1e\x02\x6d\x94\xd1\x98\x28\x16\x25\x11\x1f\x56\xaa\x25\x40\x79\x19\x7e\x98\x8b\xbf\x78\x24\xe4\x37\x80\xad\x54\x59\x6d\xfd\x74\xcc\x40\x3f\x10")); snd($sock_b, $port_a, rtp(8, 1003, 3480, 0x1234, "\x00" x 160)); # now mode 1 -rcv($sock_a, $port_b, rtpm(96, 1002, 3560, $ssrc, "\xf0\x0c\x54\x01\x1e\x01\x14\x6c\xb0\x53\xa3\x87\x8d\x76\x75\xd0\x30\x76\x70\x10\x24\x6a\x10\x62\x00")); +rcv($sock_a, $port_b, rtpm(96, 1002, 3640, $ssrc, "\xf0\x0c\x54\x01\x1e\x01\x14\x6c\xb0\x53\xa3\x87\x8d\x76\x75\xd0\x30\x76\x70\x10\x24\x6a\x10\x62\x00")); # wait for mode-change-interval Time::HiRes::usleep(220000); # 220 ms @@ -2983,10 +2983,10 @@ Time::HiRes::usleep(20000); # 20 ms, wait to be processed snd($sock_b, $port_a, rtp(8, 1004, 3640, 0x1234, "\x00" x 160)); # one more mode 1 -rcv($sock_a, $port_b, rtpm(96, 1003, 3880, $ssrc, "\xf0\x0c\x54\x10\x0f\x00\x0a\x21\x15\x55\x79\x82\x16\x54\xb8\x7c\x48\x00\xc8\x20\x40\x11\x88\x68\x00")); +rcv($sock_a, $port_b, rtpm(96, 1003, 3960, $ssrc, "\xf0\x0c\x54\x10\x0f\x00\x0a\x21\x15\x55\x79\x82\x16\x54\xb8\x7c\x48\x00\xc8\x20\x40\x11\x88\x68\x00")); snd($sock_b, $port_a, rtp(8, 1005, 3800, 0x1234, "\x00" x 160)); # now mode 2 -rcv($sock_a, $port_b, rtpm(96, 1004, 4200, $ssrc, "\xf0\x14\x41\x00\x30\x44\x41\x10\x09\x50\x63\x20\x92\x8a\x82\xf5\x85\xf8\x20\x25\x84\x92\x02\x01\xa1\xb2\x24\x06\x0f\x60\x03\x0f\xd1\x10")); +rcv($sock_a, $port_b, rtpm(96, 1004, 4280, $ssrc, "\xf0\x14\x41\x00\x30\x44\x41\x10\x09\x50\x63\x20\x92\x8a\x82\xf5\x85\xf8\x20\x25\x84\x92\x02\x01\xa1\xb2\x24\x06\x0f\x60\x03\x0f\xd1\x10")); @@ -3049,10 +3049,10 @@ snd($sock_a, $port_b, rtp(96, 2000, 4000, 0x5678, "\x10\x1c\xd0\x46\x09\xa1\xf1\ Time::HiRes::usleep(20000); # 20 ms, wait to be processed snd($sock_b, $port_a, rtp(8, 1002, 3320, 0x1234, "\x00" x 160)); # receive one more mode 8 frame, then CMR kicks in -rcv($sock_a, $port_b, rtpm(96, 1001, 3240, $ssrc, "\xf0\x44\xe0\x94\x24\x91\xd6\x45\x0d\x23\xdf\x00\x01\xad\xc9\x47\xc5\x2f\xf7\xfb\x62\x39\x06\xaf\x4d\x1c\x1e\x02\x6d\x94\xd1\x98\x28\x16\x25\x11\x1f\x56\xaa\x25\x40\x79\x19\x7e\x98\x8b\xbf\x78\x24\xe4\x37\x80\xad\x54\x59\x6d\xfd\x74\xcc\x40\x3f\x10")); +rcv($sock_a, $port_b, rtpm(96, 1001, 3320, $ssrc, "\xf0\x44\xe0\x94\x24\x91\xd6\x45\x0d\x23\xdf\x00\x01\xad\xc9\x47\xc5\x2f\xf7\xfb\x62\x39\x06\xaf\x4d\x1c\x1e\x02\x6d\x94\xd1\x98\x28\x16\x25\x11\x1f\x56\xaa\x25\x40\x79\x19\x7e\x98\x8b\xbf\x78\x24\xe4\x37\x80\xad\x54\x59\x6d\xfd\x74\xcc\x40\x3f\x10")); snd($sock_b, $port_a, rtp(8, 1003, 3480, 0x1234, "\x00" x 160)); # now mode 1 -rcv($sock_a, $port_b, rtpm(96, 1002, 3560, $ssrc, "\xf0\x0c\x54\x01\x1e\x01\x14\x6c\xb0\x53\xa3\x87\x8d\x76\x75\xd0\x30\x76\x70\x10\x24\x6a\x10\x62\x00")); +rcv($sock_a, $port_b, rtpm(96, 1002, 3640, $ssrc, "\xf0\x0c\x54\x01\x1e\x01\x14\x6c\xb0\x53\xa3\x87\x8d\x76\x75\xd0\x30\x76\x70\x10\x24\x6a\x10\x62\x00")); # wait for mode-change-interval Time::HiRes::usleep(220000); # 220 ms @@ -3063,10 +3063,10 @@ Time::HiRes::usleep(20000); # 20 ms, wait to be processed snd($sock_b, $port_a, rtp(8, 1004, 3640, 0x1234, "\x00" x 160)); # one more mode 1 -rcv($sock_a, $port_b, rtpm(96, 1003, 3880, $ssrc, "\xf0\x0c\x54\x10\x0f\x00\x0a\x21\x15\x55\x79\x82\x16\x54\xb8\x7c\x48\x00\xc8\x20\x40\x11\x88\x68\x00")); +rcv($sock_a, $port_b, rtpm(96, 1003, 3960, $ssrc, "\xf0\x0c\x54\x10\x0f\x00\x0a\x21\x15\x55\x79\x82\x16\x54\xb8\x7c\x48\x00\xc8\x20\x40\x11\x88\x68\x00")); snd($sock_b, $port_a, rtp(8, 1005, 3800, 0x1234, "\x00" x 160)); # now mode 2 -rcv($sock_a, $port_b, rtpm(96, 1004, 4200, $ssrc, "\xf0\x14\x41\x00\x30\x44\x41\x10\x09\x50\x63\x20\x92\x8a\x82\xf5\x85\xf8\x20\x25\x84\x92\x02\x01\xa1\xb2\x24\x06\x0f\x60\x03\x0f\xd1\x10")); +rcv($sock_a, $port_b, rtpm(96, 1004, 4280, $ssrc, "\xf0\x14\x41\x00\x30\x44\x41\x10\x09\x50\x63\x20\x92\x8a\x82\xf5\x85\xf8\x20\x25\x84\x92\x02\x01\xa1\xb2\x24\x06\x0f\x60\x03\x0f\xd1\x10")); @@ -3128,10 +3128,10 @@ snd($sock_a, $port_b, rtp(96, 2000, 4000, 0x5678, "\x10\x1c\xd0\x46\x09\xa1\xf1\ Time::HiRes::usleep(20000); # 20 ms, wait to be processed snd($sock_b, $port_a, rtp(8, 1002, 3320, 0x1234, "\x00" x 160)); # receive one more mode 8 frame, then CMR kicks in -rcv($sock_a, $port_b, rtpm(96, 1001, 3240, $ssrc, "\xf0\x44\xe0\x94\x24\x91\xd6\x45\x0d\x23\xdf\x00\x01\xad\xc9\x47\xc5\x2f\xf7\xfb\x62\x39\x06\xaf\x4d\x1c\x1e\x02\x6d\x94\xd1\x98\x28\x16\x25\x11\x1f\x56\xaa\x25\x40\x79\x19\x7e\x98\x8b\xbf\x78\x24\xe4\x37\x80\xad\x54\x59\x6d\xfd\x74\xcc\x40\x3f\x10")); +rcv($sock_a, $port_b, rtpm(96, 1001, 3320, $ssrc, "\xf0\x44\xe0\x94\x24\x91\xd6\x45\x0d\x23\xdf\x00\x01\xad\xc9\x47\xc5\x2f\xf7\xfb\x62\x39\x06\xaf\x4d\x1c\x1e\x02\x6d\x94\xd1\x98\x28\x16\x25\x11\x1f\x56\xaa\x25\x40\x79\x19\x7e\x98\x8b\xbf\x78\x24\xe4\x37\x80\xad\x54\x59\x6d\xfd\x74\xcc\x40\x3f\x10")); snd($sock_b, $port_a, rtp(8, 1003, 3480, 0x1234, "\x00" x 160)); # now mode 1 -rcv($sock_a, $port_b, rtpm(96, 1002, 3560, $ssrc, "\xf0\x0c\x54\x01\x1e\x01\x14\x6c\xb0\x53\xa3\x87\x8d\x76\x75\xd0\x30\x76\x70\x10\x24\x6a\x10\x62\x00")); +rcv($sock_a, $port_b, rtpm(96, 1002, 3640, $ssrc, "\xf0\x0c\x54\x01\x1e\x01\x14\x6c\xb0\x53\xa3\x87\x8d\x76\x75\xd0\x30\x76\x70\x10\x24\x6a\x10\x62\x00")); # wait for mode-change-interval Time::HiRes::usleep(220000); # 220 ms @@ -3142,10 +3142,10 @@ Time::HiRes::usleep(20000); # 20 ms, wait to be processed snd($sock_b, $port_a, rtp(8, 1004, 3640, 0x1234, "\x00" x 160)); # one more mode 1 -rcv($sock_a, $port_b, rtpm(96, 1003, 3880, $ssrc, "\xf0\x0c\x54\x10\x0f\x00\x0a\x21\x15\x55\x79\x82\x16\x54\xb8\x7c\x48\x00\xc8\x20\x40\x11\x88\x68\x00")); +rcv($sock_a, $port_b, rtpm(96, 1003, 3960, $ssrc, "\xf0\x0c\x54\x10\x0f\x00\x0a\x21\x15\x55\x79\x82\x16\x54\xb8\x7c\x48\x00\xc8\x20\x40\x11\x88\x68\x00")); snd($sock_b, $port_a, rtp(8, 1005, 3800, 0x1234, "\x00" x 160)); # now mode 2 -rcv($sock_a, $port_b, rtpm(96, 1004, 4200, $ssrc, "\xf0\x14\x41\x00\x30\x44\x41\x10\x09\x50\x63\x20\x92\x8a\x82\xf5\x85\xf8\x20\x25\x84\x92\x02\x01\xa1\xb2\x24\x06\x0f\x60\x03\x0f\xd1\x10")); +rcv($sock_a, $port_b, rtpm(96, 1004, 4280, $ssrc, "\xf0\x14\x41\x00\x30\x44\x41\x10\x09\x50\x63\x20\x92\x8a\x82\xf5\x85\xf8\x20\x25\x84\x92\x02\x01\xa1\xb2\x24\x06\x0f\x60\x03\x0f\xd1\x10")); @@ -10523,6 +10523,7 @@ snd($sock_a, $port_b, rtp(0, 1001, 3160, 0x1234, "\x00" x 160)); snd($sock_a, $port_b, rtp(0, 1002, 3320, 0x1234, "\x00" x 160)); rcv($sock_b, $port_a, rtpm(0, 1001, 3240, $ssrc, "\x00" x 240)); snd($sock_a, $port_b, rtp(0, 1003, 3480, 0x1234, "\x00" x 160)); +Time::HiRes::usleep(1000); snd($sock_a, $port_b, rtp(0, 1004, 3640, 0x1234, "\x00" x 160)); rcv($sock_b, $port_a, rtpm(0, 1002, 3480, $ssrc, "\x00" x 240)); @@ -10544,6 +10545,7 @@ rcv($sock_a, $port_b, rtpm(0, 4005, 5800, $ssrc, "\x88" x 160)); # B->A: 4x 10 ms packet -> 2x 20 ms snd($sock_b, $port_a, rtp(0, 4002, 5960, 0x4567, "\x88" x 80)); +Time::HiRes::usleep(1000); snd($sock_b, $port_a, rtp(0, 4003, 6040, 0x4567, "\x88" x 80)); rcv($sock_a, $port_b, rtpm(0, 4006, 5960, $ssrc, "\x88" x 160)); # out of order packet input @@ -10552,6 +10554,7 @@ Time::HiRes::usleep(10000); snd($sock_b, $port_a, rtp(0, 4004, 6120, 0x4567, "\x88" x 80)); rcv($sock_a, $port_b, rtpm(0, 4007, 6120, $ssrc, "\x88" x 160)); snd($sock_b, $port_a, rtp(0, 4006, 6280, 0x4567, "\x88" x 80)); +Time::HiRes::usleep(1000); snd($sock_b, $port_a, rtp(0, 4007, 6360, 0x4567, "\x88" x 80)); rcv($sock_a, $port_b, rtpm(0, 4008, 6280, $ssrc, "\x88" x 160)); @@ -10683,6 +10686,7 @@ Time::HiRes::usleep(20000); # 20 ms, needed to ensure that packet 1000 is receiv snd($sock_b, $port_a, rtp(0, 4001, 5240, 0x4567, "\x88" x 240)); ($ssrc) = rcv($sock_a, $port_b, rtpm(0, 4000, 5000, -1, "\x88" x 400)); snd($sock_b, $port_a, rtp(0, 4002, 5480, 0x4567, "\x88" x 240)); +Time::HiRes::usleep(1000); snd($sock_b, $port_a, rtp(0, 4003, 5720, 0x4567, "\x88" x 240)); rcv($sock_a, $port_b, rtpm(0, 4001, 5400, $ssrc, "\x88" x 400)); # B->A: add another 30 ms for another full 50 ms @@ -10756,6 +10760,7 @@ Time::HiRes::usleep(20000); # 20 ms, needed to ensure that packet 1000 is receiv snd($sock_b, $port_a, rtp(0, 4001, 5240, 0x4567, "\x88" x 240)); ($ssrc) = rcv($sock_a, $port_b, rtpm(0, 4000, 5000, -1, "\x88" x 400)); snd($sock_b, $port_a, rtp(0, 4002, 5480, 0x4567, "\x88" x 240)); +Time::HiRes::usleep(1000); snd($sock_b, $port_a, rtp(0, 4003, 5720, 0x4567, "\x88" x 240)); rcv($sock_a, $port_b, rtpm(0, 4001, 5400, $ssrc, "\x88" x 400)); # B->A: add another 30 ms for another full 50 ms @@ -10829,6 +10834,7 @@ Time::HiRes::usleep(20000); # 20 ms, needed to ensure that packet 1000 is receiv snd($sock_b, $port_a, rtp(0, 4001, 5240, 0x4567, "\x88" x 240)); ($ssrc) = rcv($sock_a, $port_b, rtpm(0, 4000, 5000, -1, "\x88" x 400)); snd($sock_b, $port_a, rtp(0, 4002, 5480, 0x4567, "\x88" x 240)); +Time::HiRes::usleep(1000); snd($sock_b, $port_a, rtp(0, 4003, 5720, 0x4567, "\x88" x 240)); rcv($sock_a, $port_b, rtpm(0, 4001, 5400, $ssrc, "\x88" x 400)); # B->A: add another 30 ms for another full 50 ms @@ -10901,6 +10907,7 @@ Time::HiRes::usleep(20000); # 20 ms, needed to ensure that packet 1000 is receiv snd($sock_b, $port_a, rtp(0, 4001, 5240, 0x4567, "\x88" x 240)); ($ssrc) = rcv($sock_a, $port_b, rtpm(0, 4000, 5000, -1, "\x88" x 400)); snd($sock_b, $port_a, rtp(0, 4002, 5480, 0x4567, "\x88" x 240)); +Time::HiRes::usleep(1000); snd($sock_b, $port_a, rtp(0, 4003, 5720, 0x4567, "\x88" x 240)); rcv($sock_a, $port_b, rtpm(0, 4001, 5400, $ssrc, "\x88" x 400)); # B->A: add another 30 ms for another full 50 ms