123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187 |
- /*
- * SpanDSP - a series of DSP components for telephony
- *
- * rfc2198_sim.c - Simulate the behaviour of RFC2198 (or UDPTL) redundancy.
- *
- * Written by Steve Underwood <steveu@coppice.org>
- *
- * Copyright (C) 2007 Steve Underwood
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2, as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
- #if defined(HAVE_CONFIG_H)
- #include "config.h"
- #endif
- #include <stdlib.h>
- #include <unistd.h>
- #include <inttypes.h>
- #include <string.h>
- #include <time.h>
- #include <stdio.h>
- #include <fcntl.h>
- #if defined(HAVE_TGMATH_H)
- #include <tgmath.h>
- #endif
- #if defined(HAVE_MATH_H)
- #define GEN_CONST
- #include <math.h>
- #endif
- #if defined(HAVE_STDBOOL_H)
- #include <stdbool.h>
- #else
- #include "spandsp/stdbool.h"
- #endif
- #include "floating_fudge.h"
- #include "spandsp.h"
- #include "spandsp/g1050.h"
- #include "spandsp/rfc2198_sim.h"
- #define PACKET_LOSS_TIME -1
- SPAN_DECLARE(rfc2198_sim_state_t *) rfc2198_sim_init(int model,
- int speed_pattern,
- int packet_size,
- int packet_rate,
- int redundancy_depth)
- {
- rfc2198_sim_state_t *s;
- if ((s = (rfc2198_sim_state_t *) malloc(sizeof(*s))) == NULL)
- return NULL;
- memset(s, 0, sizeof(*s));
- s->g1050 = g1050_init(model, speed_pattern, packet_size, packet_rate);
- s->redundancy_depth = redundancy_depth;
- return s;
- }
- /*- End of function --------------------------------------------------------*/
- SPAN_DECLARE(int) rfc2198_sim_free(rfc2198_sim_state_t *s)
- {
- g1050_free(s->g1050);
- free(s);
- return 0;
- }
- /*- End of function --------------------------------------------------------*/
- SPAN_DECLARE(int) rfc2198_sim_put(rfc2198_sim_state_t *s,
- const uint8_t buf[],
- int len,
- int seq_no,
- double departure_time)
- {
- uint8_t buf2[8192];
- uint8_t *p;
- uint16_t *q;
- int slot;
- int i;
- /* Save the packet in the history buffer */
- memcpy(s->tx_pkt[s->next_pkt], buf, len);
- s->tx_pkt_len[s->next_pkt] = len;
- s->tx_pkt_seq_no[s->next_pkt] = seq_no;
- /* Construct the redundant packet */
- p = buf2;
- slot = s->next_pkt;
- q = (uint16_t *) p;
- *q = s->redundancy_depth;
- p += sizeof(uint16_t);
- for (i = 0; i < s->redundancy_depth; i++)
- {
- q = (uint16_t *) p;
- *q = s->tx_pkt_len[slot];
- p += sizeof(uint16_t);
- memcpy(p, s->tx_pkt[slot], s->tx_pkt_len[slot]);
- p += s->tx_pkt_len[slot];
- slot = (slot - 1) & 0x1F;
- }
- s->next_pkt = (s->next_pkt + 1) & 0x1F;
- return g1050_put(s->g1050, buf2, p - buf2, seq_no, departure_time);
- }
- /*- End of function --------------------------------------------------------*/
- SPAN_DECLARE(int) rfc2198_sim_get(rfc2198_sim_state_t *s,
- uint8_t buf[],
- int max_len,
- double current_time,
- int *seq_no,
- double *departure_time,
- double *arrival_time)
- {
- int len;
- int lenx;
- int seq_nox;
- int i;
- #if defined(_MSC_VER)
- uint8_t *bufx = (uint8_t *) _alloca(s->redundancy_depth*1024);
- #else
- uint8_t bufx[s->redundancy_depth*1024];
- #endif
- uint8_t *p;
- uint16_t *q;
- int redundancy_depth;
- if (s->rx_queued_pkts)
- {
- /* We have some stuff from the last g1050_get() still to deliver */
- s->rx_queued_pkts--;
- memcpy(buf, s->rx_pkt[s->rx_queued_pkts], s->rx_pkt_len[s->rx_queued_pkts]);
- *seq_no = s->rx_pkt_seq_no[s->rx_queued_pkts];
- return s->rx_pkt_len[s->rx_queued_pkts];
- }
- len = g1050_get(s->g1050, bufx, s->redundancy_depth*1024, current_time, &seq_nox, departure_time, arrival_time);
- if (len > 0)
- {
- p = bufx;
- q = (uint16_t *) p;
- redundancy_depth = *q;
- p += sizeof(uint16_t);
- i = 0;
- if (seq_nox > s->next_seq_no)
- {
- /* Some stuff is missing. Try to fill it in. */
- s->rx_queued_pkts = seq_nox - s->next_seq_no;
- if (s->rx_queued_pkts >= redundancy_depth)
- s->rx_queued_pkts = redundancy_depth - 1;
- for (i = 0; i < s->rx_queued_pkts; i++)
- {
- q = (uint16_t *) p;
- s->rx_pkt_len[i] = *q;
- p += sizeof(uint16_t);
- memcpy(s->rx_pkt[i], p, s->rx_pkt_len[i]);
- s->rx_pkt_seq_no[i] = seq_nox - i;
- p += s->rx_pkt_len[i];
- }
- }
- *seq_no = seq_nox - i;
- q = (uint16_t *) p;
- lenx = *q;
- p += sizeof(uint16_t);
- memcpy(buf, p, lenx);
- s->next_seq_no = seq_nox + 1;
- }
- else
- {
- lenx = len;
- }
- return lenx;
- }
- /*- End of function --------------------------------------------------------*/
- /*- End of file ------------------------------------------------------------*/
|