rfc2198_sim.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  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. #if defined(HAVE_CONFIG_H)
  26. #include "config.h"
  27. #endif
  28. #include <stdlib.h>
  29. #include <unistd.h>
  30. #include <inttypes.h>
  31. #include <string.h>
  32. #include <time.h>
  33. #include <stdio.h>
  34. #include <fcntl.h>
  35. #if defined(HAVE_TGMATH_H)
  36. #include <tgmath.h>
  37. #endif
  38. #if defined(HAVE_MATH_H)
  39. #define GEN_CONST
  40. #include <math.h>
  41. #endif
  42. #if defined(HAVE_STDBOOL_H)
  43. #include <stdbool.h>
  44. #else
  45. #include "spandsp/stdbool.h"
  46. #endif
  47. #include "floating_fudge.h"
  48. #include "spandsp.h"
  49. #include "spandsp/g1050.h"
  50. #include "spandsp/rfc2198_sim.h"
  51. #define PACKET_LOSS_TIME -1
  52. SPAN_DECLARE(rfc2198_sim_state_t *) rfc2198_sim_init(int model,
  53. int speed_pattern,
  54. int packet_size,
  55. int packet_rate,
  56. int redundancy_depth)
  57. {
  58. rfc2198_sim_state_t *s;
  59. if ((s = (rfc2198_sim_state_t *) malloc(sizeof(*s))) == NULL)
  60. return NULL;
  61. memset(s, 0, sizeof(*s));
  62. s->g1050 = g1050_init(model, speed_pattern, packet_size, packet_rate);
  63. s->redundancy_depth = redundancy_depth;
  64. return s;
  65. }
  66. /*- End of function --------------------------------------------------------*/
  67. SPAN_DECLARE(int) rfc2198_sim_free(rfc2198_sim_state_t *s)
  68. {
  69. g1050_free(s->g1050);
  70. free(s);
  71. return 0;
  72. }
  73. /*- End of function --------------------------------------------------------*/
  74. SPAN_DECLARE(int) rfc2198_sim_put(rfc2198_sim_state_t *s,
  75. const uint8_t buf[],
  76. int len,
  77. int seq_no,
  78. double departure_time)
  79. {
  80. uint8_t buf2[8192];
  81. uint8_t *p;
  82. uint16_t *q;
  83. int slot;
  84. int i;
  85. /* Save the packet in the history buffer */
  86. memcpy(s->tx_pkt[s->next_pkt], buf, len);
  87. s->tx_pkt_len[s->next_pkt] = len;
  88. s->tx_pkt_seq_no[s->next_pkt] = seq_no;
  89. /* Construct the redundant packet */
  90. p = buf2;
  91. slot = s->next_pkt;
  92. q = (uint16_t *) p;
  93. *q = s->redundancy_depth;
  94. p += sizeof(uint16_t);
  95. for (i = 0; i < s->redundancy_depth; i++)
  96. {
  97. q = (uint16_t *) p;
  98. *q = s->tx_pkt_len[slot];
  99. p += sizeof(uint16_t);
  100. memcpy(p, s->tx_pkt[slot], s->tx_pkt_len[slot]);
  101. p += s->tx_pkt_len[slot];
  102. slot = (slot - 1) & 0x1F;
  103. }
  104. s->next_pkt = (s->next_pkt + 1) & 0x1F;
  105. return g1050_put(s->g1050, buf2, p - buf2, seq_no, departure_time);
  106. }
  107. /*- End of function --------------------------------------------------------*/
  108. SPAN_DECLARE(int) rfc2198_sim_get(rfc2198_sim_state_t *s,
  109. uint8_t buf[],
  110. int max_len,
  111. double current_time,
  112. int *seq_no,
  113. double *departure_time,
  114. double *arrival_time)
  115. {
  116. int len;
  117. int lenx;
  118. int seq_nox;
  119. int i;
  120. #if defined(_MSC_VER)
  121. uint8_t *bufx = (uint8_t *) _alloca(s->redundancy_depth*1024);
  122. #else
  123. uint8_t bufx[s->redundancy_depth*1024];
  124. #endif
  125. uint8_t *p;
  126. uint16_t *q;
  127. int redundancy_depth;
  128. if (s->rx_queued_pkts)
  129. {
  130. /* We have some stuff from the last g1050_get() still to deliver */
  131. s->rx_queued_pkts--;
  132. memcpy(buf, s->rx_pkt[s->rx_queued_pkts], s->rx_pkt_len[s->rx_queued_pkts]);
  133. *seq_no = s->rx_pkt_seq_no[s->rx_queued_pkts];
  134. return s->rx_pkt_len[s->rx_queued_pkts];
  135. }
  136. len = g1050_get(s->g1050, bufx, s->redundancy_depth*1024, current_time, &seq_nox, departure_time, arrival_time);
  137. if (len > 0)
  138. {
  139. p = bufx;
  140. q = (uint16_t *) p;
  141. redundancy_depth = *q;
  142. p += sizeof(uint16_t);
  143. i = 0;
  144. if (seq_nox > s->next_seq_no)
  145. {
  146. /* Some stuff is missing. Try to fill it in. */
  147. s->rx_queued_pkts = seq_nox - s->next_seq_no;
  148. if (s->rx_queued_pkts >= redundancy_depth)
  149. s->rx_queued_pkts = redundancy_depth - 1;
  150. for (i = 0; i < s->rx_queued_pkts; i++)
  151. {
  152. q = (uint16_t *) p;
  153. s->rx_pkt_len[i] = *q;
  154. p += sizeof(uint16_t);
  155. memcpy(s->rx_pkt[i], p, s->rx_pkt_len[i]);
  156. s->rx_pkt_seq_no[i] = seq_nox - i;
  157. p += s->rx_pkt_len[i];
  158. }
  159. }
  160. *seq_no = seq_nox - i;
  161. q = (uint16_t *) p;
  162. lenx = *q;
  163. p += sizeof(uint16_t);
  164. memcpy(buf, p, lenx);
  165. s->next_seq_no = seq_nox + 1;
  166. }
  167. else
  168. {
  169. lenx = len;
  170. }
  171. return lenx;
  172. }
  173. /*- End of function --------------------------------------------------------*/
  174. /*- End of file ------------------------------------------------------------*/