comparison spandsp-0.0.6pre17/spandsp-sim/rfc2198_sim.c @ 4:26cd8f1ef0b1

import spandsp-0.0.6pre17
author Peter Meerwald <pmeerw@cosy.sbg.ac.at>
date Fri, 25 Jun 2010 15:50:58 +0200
parents
children
comparison
equal deleted inserted replaced
3:c6c5a16ce2f2 4:26cd8f1ef0b1
1 /*
2 * SpanDSP - a series of DSP components for telephony
3 *
4 * rfc2198_sim.c - Simulate the behaviour of RFC2198 (or UDPTL) redundancy.
5 *
6 * Written by Steve Underwood <steveu@coppice.org>
7 *
8 * Copyright (C) 2007 Steve Underwood
9 *
10 * All rights reserved.
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2, as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 * $Id: rfc2198_sim.c,v 1.10 2009/06/01 16:27:12 steveu Exp $
26 */
27
28 #if defined(HAVE_CONFIG_H)
29 #include "config.h"
30 #endif
31
32 #include <stdlib.h>
33 #include <unistd.h>
34 #include <inttypes.h>
35 #include <string.h>
36 #include <time.h>
37 #include <stdio.h>
38 #include <fcntl.h>
39 #if defined(HAVE_TGMATH_H)
40 #include <tgmath.h>
41 #endif
42 #if defined(HAVE_MATH_H)
43 #define GEN_CONST
44 #include <math.h>
45 #endif
46 #include "floating_fudge.h"
47
48 #include "spandsp.h"
49 #include "spandsp/g1050.h"
50 #include "spandsp/rfc2198_sim.h"
51
52 #define PACKET_LOSS_TIME -1
53
54 #define FALSE 0
55 #define TRUE (!FALSE)
56
57 SPAN_DECLARE(rfc2198_sim_state_t *) rfc2198_sim_init(int model,
58 int speed_pattern,
59 int packet_size,
60 int packet_rate,
61 int redundancy_depth)
62 {
63 rfc2198_sim_state_t *s;
64
65 if ((s = (rfc2198_sim_state_t *) malloc(sizeof(*s))) == NULL)
66 return NULL;
67 memset(s, 0, sizeof(*s));
68
69 s->g1050 = g1050_init(model, speed_pattern, packet_size, packet_rate);
70 s->redundancy_depth = redundancy_depth;
71 return s;
72 }
73 /*- End of function --------------------------------------------------------*/
74
75 SPAN_DECLARE(int) rfc2198_sim_put(rfc2198_sim_state_t *s,
76 const uint8_t buf[],
77 int len,
78 int seq_no,
79 double departure_time)
80 {
81 uint8_t buf2[8192];
82 uint8_t *p;
83 uint16_t *q;
84 int slot;
85 int i;
86
87 /* Save the packet in the history buffer */
88 memcpy(s->tx_pkt[s->next_pkt], buf, len);
89 s->tx_pkt_len[s->next_pkt] = len;
90 s->tx_pkt_seq_no[s->next_pkt] = seq_no;
91
92 /* Construct the redundant packet */
93 p = buf2;
94 slot = s->next_pkt;
95 q = (uint16_t *) p;
96 *q = s->redundancy_depth;
97 p += sizeof(uint16_t);
98 for (i = 0; i < s->redundancy_depth; i++)
99 {
100 q = (uint16_t *) p;
101 *q = s->tx_pkt_len[slot];
102 p += sizeof(uint16_t);
103 memcpy(p, s->tx_pkt[slot], s->tx_pkt_len[slot]);
104 p += s->tx_pkt_len[slot];
105 slot = (slot - 1) & 0x1F;
106 }
107 s->next_pkt = (s->next_pkt + 1) & 0x1F;
108 return g1050_put(s->g1050, buf2, p - buf2, seq_no, departure_time);
109 }
110 /*- End of function --------------------------------------------------------*/
111
112 SPAN_DECLARE(int) rfc2198_sim_get(rfc2198_sim_state_t *s,
113 uint8_t buf[],
114 int max_len,
115 double current_time,
116 int *seq_no,
117 double *departure_time,
118 double *arrival_time)
119 {
120 int len;
121 int lenx;
122 int seq_nox;
123 int i;
124 #if defined(_MSC_VER)
125 uint8_t *bufx = (uint8_t *) _alloca(s->redundancy_depth*1024);
126 #else
127 uint8_t bufx[s->redundancy_depth*1024];
128 #endif
129 uint8_t *p;
130 uint16_t *q;
131 int redundancy_depth;
132
133 if (s->rx_queued_pkts)
134 {
135 /* We have some stuff from the last g1050_get() still to deliver */
136 s->rx_queued_pkts--;
137 memcpy(buf, s->rx_pkt[s->rx_queued_pkts], s->rx_pkt_len[s->rx_queued_pkts]);
138 *seq_no = s->rx_pkt_seq_no[s->rx_queued_pkts];
139 return s->rx_pkt_len[s->rx_queued_pkts];
140 }
141 len = g1050_get(s->g1050, bufx, s->redundancy_depth*1024, current_time, &seq_nox, departure_time, arrival_time);
142 if (len > 0)
143 {
144 p = bufx;
145 q = (uint16_t *) p;
146 redundancy_depth = *q;
147 p += sizeof(uint16_t);
148 i = 0;
149 if (seq_nox > s->next_seq_no)
150 {
151 /* Some stuff is missing. Try to fill it in. */
152 s->rx_queued_pkts = seq_nox - s->next_seq_no;
153 if (s->rx_queued_pkts >= redundancy_depth)
154 s->rx_queued_pkts = redundancy_depth - 1;
155 for (i = 0; i < s->rx_queued_pkts; i++)
156 {
157 q = (uint16_t *) p;
158 s->rx_pkt_len[i] = *q;
159 p += sizeof(uint16_t);
160 memcpy(s->rx_pkt[i], p, s->rx_pkt_len[i]);
161 s->rx_pkt_seq_no[i] = seq_nox - i;
162 p += s->rx_pkt_len[i];
163 }
164 }
165 *seq_no = seq_nox - i;
166 q = (uint16_t *) p;
167 lenx = *q;
168 p += sizeof(uint16_t);
169 memcpy(buf, p, lenx);
170 s->next_seq_no = seq_nox + 1;
171 }
172 else
173 {
174 lenx = len;
175 }
176 return lenx;
177 }
178 /*- End of function --------------------------------------------------------*/
179 /*- End of file ------------------------------------------------------------*/

Repositories maintained by Peter Meerwald, pmeerw@pmeerw.net.