Index: channels/chan_iax2.c =================================================================== RCS file: /usr/cvsroot/asterisk/channels/chan_iax2.c,v retrieving revision 1.287 diff -a -u -r1.287 chan_iax2.c --- channels/chan_iax2.c 15 May 2005 23:26:45 -0000 1.287 +++ channels/chan_iax2.c 17 May 2005 20:12:56 -0000 @@ -186,6 +186,12 @@ static int iaxtrunkdebug = 0; static int test_losspct = 0; +#ifdef IAXTESTS +static int test_late = 0; +static int test_resync = 0; +static int test_jit = 0; +static int test_jitpct = 0; +#endif /* IAXTESTS */ static char accountcode[20]; static int amaflags = 0; @@ -1788,6 +1794,40 @@ return RESULT_SUCCESS; } +#ifdef IAXTESTS +static int iax2_test_late(int fd, int argc, char *argv[]) +{ + if (argc != 4) + return RESULT_SHOWUSAGE; + + test_late = atoi(argv[3]); + + return RESULT_SUCCESS; +} + +static int iax2_test_resync(int fd, int argc, char *argv[]) +{ + if (argc != 4) + return RESULT_SHOWUSAGE; + + test_resync = atoi(argv[3]); + + return RESULT_SUCCESS; +} + +static int iax2_test_jitter(int fd, int argc, char *argv[]) +{ + if (argc < 4 || argc > 5) + return RESULT_SHOWUSAGE; + + test_jit = atoi(argv[3]); + if (argc == 5) + test_jitpct = atoi(argv[4]); + + return RESULT_SUCCESS; +} +#endif /* IAXTESTS */ + /*--- iax2_show_peer: Show one peer in detail ---*/ static int iax2_show_peer(int fd, int argc, char *argv[]) { @@ -3504,6 +3544,9 @@ since we received (or would have received) the frame with timestamp 0 */ struct timeval tv; int ms; +#ifdef IAXTESTS + int jit; +#endif /* IAXTESTS */ /* Setup rxcore if necessary */ if (!p->rxcore.tv_sec && !p->rxcore.tv_usec) { gettimeofday(&p->rxcore, NULL); @@ -3526,6 +3569,20 @@ gettimeofday(&tv, NULL); ms = (tv.tv_sec - p->rxcore.tv_sec) * 1000 + (1000000 + tv.tv_usec - p->rxcore.tv_usec) / 1000 - 1000; +#ifdef IAXTESTS + if (test_jit) { + if (!test_jitpct || ((100.0 * rand() / (RAND_MAX + 1.0)) < test_jitpct)) { + jit = (int)((float)test_jit * rand() / (RAND_MAX + 1.0)); + if ((int)(2.0 * rand() / (RAND_MAX + 1.0))) + jit = -jit; + ms += jit; + } + } + if (test_late) { + ms += test_late; + test_late = 0; + } +#endif /* IAXTESTS */ return ms; } @@ -4456,6 +4513,17 @@ static char iax2_test_losspct_usage[] = "Usage: iax2 test losspct \n" " For testing, throws away percent of incoming packets\n"; +#ifdef IAXTESTS +static char iax2_test_late_usage[] = +"Usage: iax2 test late \n" +" For testing, count the next frame as ms late\n"; +static char iax2_test_resync_usage[] = +"Usage: iax2 test resync \n" +" For testing, adjust all future frames by ms\n"; +static char iax2_test_jitter_usage[] = +"Usage: iax2 test jitter \n" +" For testing, simulate maximum jitter of +/- on percentage of packets. If is not specified, adds jitter to all packets.\n"; +#endif /* IAXTESTS */ static struct ast_cli_entry cli_show_users = { { "iax2", "show", "users", NULL }, iax2_show_users, "Show defined IAX users", show_users_usage }; @@ -4477,6 +4545,14 @@ { { "iax2", "no", "debug", NULL }, iax2_no_debug, "Disable IAX debugging", no_debug_usage }; static struct ast_cli_entry cli_test_losspct = { { "iax2", "test", "losspct", NULL }, iax2_test_losspct, "Set IAX2 incoming frame loss percentage", iax2_test_losspct_usage }; +#ifdef IAXTESTS +static struct ast_cli_entry cli_test_late = + { { "iax2", "test", "late", NULL }, iax2_test_late, "Test the receipt of a late frame", iax2_test_late_usage }; +static struct ast_cli_entry cli_test_resync = + { { "iax2", "test", "resync", NULL }, iax2_test_resync, "Test a resync in received timestamps", iax2_test_resync_usage }; +static struct ast_cli_entry cli_test_jitter = + { { "iax2", "test", "jitter", NULL }, iax2_test_jitter, "Simulates jitter for testing", iax2_test_jitter_usage }; +#endif /* IAXTESTS */ static int iax2_write(struct ast_channel *c, struct ast_frame *f) { @@ -6344,6 +6420,13 @@ fr.oseqno = fh->oseqno; fr.iseqno = fh->iseqno; fr.ts = ntohl(fh->ts); +#ifdef IAXTESTS + if (test_resync) { + if (option_debug) + ast_log(LOG_DEBUG, "Simulating frame ts resync, was %u now %u\n", fr.ts, fr.ts + test_resync); + fr.ts += test_resync; + } +#endif /* IAXTESTS */ #if 0 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX && @@ -7320,6 +7403,11 @@ f.data = buf + sizeof(struct ast_iax2_video_hdr); else f.data = NULL; +#ifdef IAXTESTS + if (test_resync) { + fr.ts = (iaxs[fr.callno]->last & 0xFFFF8000L) | ((ntohs(mh->ts) + test_resync) & 0x7fff); + } else +#endif /* IAXTESTS */ fr.ts = (iaxs[fr.callno]->last & 0xFFFF8000L) | (ntohs(mh->ts) & 0x7fff); } else { /* A mini frame */ @@ -7342,6 +7430,11 @@ f.data = buf + sizeof(struct ast_iax2_mini_hdr); else f.data = NULL; +#ifdef IAXTESTS + if (test_resync) { + fr.ts = (iaxs[fr.callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff); + } else +#endif /* IAXTESTS */ fr.ts = (iaxs[fr.callno]->last & 0xFFFF0000L) | ntohs(mh->ts); /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */ } @@ -8949,6 +9042,11 @@ ast_cli_unregister(&cli_trunk_debug); ast_cli_unregister(&cli_no_debug); ast_cli_unregister(&cli_test_losspct); +#ifdef IAXTESTS + ast_cli_unregister(&cli_test_late); + ast_cli_unregister(&cli_test_resync); + ast_cli_unregister(&cli_test_jitter); +#endif /* IAXTESTS */ ast_cli_unregister(&cli_set_jitter); ast_cli_unregister(&cli_show_stats); ast_cli_unregister(&cli_show_cache); @@ -9037,6 +9135,11 @@ ast_cli_register(&cli_trunk_debug); ast_cli_register(&cli_no_debug); ast_cli_register(&cli_test_losspct); +#ifdef IAXTESTS + ast_cli_register(&cli_test_late); + ast_cli_register(&cli_test_resync); + ast_cli_register(&cli_test_jitter); +#endif /* IAXTESTS */ ast_cli_register(&cli_set_jitter); ast_cli_register(&cli_show_stats); ast_cli_register(&cli_show_cache);