Example #1
0
void
test_battery()
{
        int retval;
        struct libdaemon_config *cfg;

        /* ensure run before init fails */
        retval = test_run();

        /* ensure destroy before init fails */
        retval = test_destroy();

        /* ensure init works */
        retval = test_init();

        cfg = daemon_getconfig();
        if ((NULL != cfg) && (NULL != cfg->rundir))
            printf("[+] rundir: %s\n\n", cfg->rundir);

        /* ensure double init fails */
        retval = test_init();

        /* test run works */
//        retval = test_run();

        /* test destroy works */
        retval = test_destroy();

}
Example #2
0
int
main(int argc, char **argv)
{
	test_prepare();
	test_allow();

	test_0();
	getchar();
#if 1
	test_allowed_read();
	getchar();
	test_allowed_write();
	getchar();
	test_destroy();

	test_prepare();
	test_allow();
	test_0();
	getchar();
#endif
	test_not_allowed_read();
	getchar();
	test_not_allowed_write();
	getchar();

	test_destroy();

	return (0);
}
Example #3
0
/* Test several threads running (*body)(struct test *m) for increasing settings
   of m->iterations, until about timeout_s to 2*timeout_s seconds have elapsed.
   If extra!=NULL, run (*extra)(m) in an additional thread.  */
static void test(const char *name, void (*body)(void *m),
                 void (*extra)(void *m), int timeout_s) {
  gpr_int64 iterations = 1024;
  struct test *m;
  gpr_timespec start = gpr_now(GPR_CLOCK_REALTIME);
  gpr_timespec time_taken;
  gpr_timespec deadline = gpr_time_add(
      start, gpr_time_from_micros(timeout_s * 1000000, GPR_TIMESPAN));
  fprintf(stderr, "%s:", name);
  while (gpr_time_cmp(gpr_now(GPR_CLOCK_REALTIME), deadline) < 0) {
    iterations <<= 1;
    fprintf(stderr, " %ld", (long)iterations);
    m = test_new(10, iterations);
    if (extra != NULL) {
      gpr_thd_id id;
      GPR_ASSERT(gpr_thd_new(&id, extra, m, NULL));
      m->done++; /* one more thread to wait for */
    }
    test_create_threads(m, body);
    test_wait(m);
    if (m->counter != m->threads * m->iterations) {
      fprintf(stderr, "counter %ld  threads %d  iterations %ld\n",
              (long)m->counter, m->threads, (long)m->iterations);
      GPR_ASSERT(0);
    }
    test_destroy(m);
  }
  time_taken = gpr_time_sub(gpr_now(GPR_CLOCK_REALTIME), start);
  fprintf(stderr, " done %ld.%09d s\n", (long)time_taken.tv_sec,
          (int)time_taken.tv_nsec);
}
Example #4
0
/*****************************************************************************
 * main()
 */
int main(int argc, char *argv[])
{
    pj_status_t status;

    if (init_options(argc, argv) != 0)
	return 1;


    /* Init */
    status = test_init();
    if (status != PJ_SUCCESS)
	return 1;

    /* Print parameters */
    PJ_LOG(3,(THIS_FILE, "Starting simulation. Parameters: "));
    PJ_LOG(3,(THIS_FILE, "  Codec=%.*s, tx_ptime=%d, rx_ptime=%d",
	      (int)g_app.cfg.codec.slen,
	      g_app.cfg.codec.ptr,
	      g_app.cfg.tx_ptime,
	      g_app.cfg.rx_ptime));
    PJ_LOG(3,(THIS_FILE, " Loss avg=%d%%, min_burst=%d, max_burst=%d",
	      g_app.cfg.tx_pct_avg_lost,
	      g_app.cfg.tx_min_lost_burst,
	      g_app.cfg.tx_max_lost_burst));
    PJ_LOG(3,(THIS_FILE, " TX jitter min=%dms, max=%dms",
	      g_app.cfg.tx_min_jitter, 
	      g_app.cfg.tx_max_jitter));
    PJ_LOG(3,(THIS_FILE, " RX jb init:%dms, min_pre=%dms, max_pre=%dms, max=%dms",
	      g_app.cfg.rx_jb_init,
	      g_app.cfg.rx_jb_min_pre,
	      g_app.cfg.rx_jb_max_pre,
	      g_app.cfg.rx_jb_max));
    PJ_LOG(3,(THIS_FILE, " RX sound burst:%d frames",
	      g_app.cfg.rx_snd_burst));
    PJ_LOG(3,(THIS_FILE, " DTX=%d, PLC=%d",
	      g_app.cfg.tx_dtx, g_app.cfg.rx_plc));

    /* Run test loop */
    test_loop(g_app.cfg.duration_msec);

    /* Print statistics */
    PJ_LOG(3,(THIS_FILE, "Simulation done"));
    PJ_LOG(3,(THIS_FILE, " TX packets=%u, dropped=%u/%5.1f%%",
	      g_app.tx->state.tx.total_tx,
	      g_app.tx->state.tx.total_lost,
	      (float)(g_app.tx->state.tx.total_lost * 100.0 / g_app.tx->state.tx.total_tx)));

    /* Done */
    test_destroy();

    return 0;
}
Example #5
0
int main(void)
{
	struct test *t = test_create(100);

	mutex_lock(&t->mutex);

	/* Run the producer until the queue is full */
 	t->producer_blocked = FALSE;
	tasklet_later(&t->producer, producer);

	while (!t->producer_blocked)
		cond_wait(&t->cond, &t->mutex);

	tasklet_stop(&t->producer);
	assert(t->producer_count == 100);

	/* Run the consumer until the queue is empty */
	t->consumer_blocked = FALSE;
	tasklet_later(&t->consumer, consumer);

	while (!t->consumer_blocked)
		cond_wait(&t->cond, &t->mutex);

	assert(t->consumer_count == 100);

	/* Run the producer and the consumer together until 200 items
	   have been produced. */
 	t->producer_blocked = FALSE;
	t->consumer_blocked = FALSE;
	tasklet_later(&t->producer, producer);

	while (t->producer_count < 200)
		cond_wait(&t->cond, &t->mutex);

	while (!t->consumer_blocked)
		cond_wait(&t->cond, &t->mutex);

	assert(t->consumer_count == t->producer_count);

	test_destroy(t);
	return 0;
}
Example #6
0
int main()
{
	int failures = 0;
	printf("Starting linked list test...\n");
	failures += test_create();
	failures += test_append_element();
	failures += test_prepend_element();
	failures += test_prepend_five();
	failures += test_append_five();
	failures += test_add_many();
	failures += test_add_struct();
	failures += test_append_list();
	failures += test_append_list_empty();
	failures += test_prepend_list();
	failures += test_prepend_list_empty();
	failures += test_reverse();
	failures += test_shallow_copy();
	failures += test_shift();
	failures += test_reduce();
	failures += test_insert();
	failures += test_insert_at_head();
	failures += test_insert_at_tail();
	failures += test_delete();
	failures += test_delete_at_head();
	failures += test_delete_at_tail();
	failures += test_index();
	failures += test_destroy();
	failures += test_clear();
	failures += test_llist_index_of_f();
	failures += test_to_array();
	failures += test_delete_last();
	failures += test_delete_last_few();
	if (0 == failures) {
		printf("All tests ok.\n");
	} else {
		printf("%d test(s) FAILED.\n", failures);
		return 1;
	}

	return 0;
}
int test_runall (sortfunc const * funcs, int nfuncs)
{
  int * input;
  int * output;
  int ifunc, icheck, pass, allpass;
  
  allpass = 1;
  for (ifunc = 0; ifunc < nfuncs; ++ifunc) {
    
    printf ("Checking %s\n", funcs[ifunc].name);
    
    pass = 1;
    for (icheck = 0; icheck < 10; ++icheck) {
      test_create (icheck, &input, &output);
      funcs[ifunc].func (output, 10);
      if ( ! test_check (input, output)) {
	pass = 0;
      }
      test_destroy (input, output);
    }
    
    if (pass) {
      printf ("%s passed\n", funcs[ifunc].name);
    }
    else {
      printf ("%s FAILED\n", funcs[ifunc].name);
      allpass = 0;
    }
    
  }
  
  if (allpass) {
    printf ("\nAll tests passed.\n");
  }
  else {
    printf ("\nThere were FAILURES.\n");
  }
  
  return allpass ? 0 : 1;
}
Example #8
0
struct test_filter *test_create(const char *settings, obs_source_t source)
{
	struct test_filter *tf = bmalloc(sizeof(struct test_filter));
	char *effect_file;
	memset(tf, 0, sizeof(struct test_filter));

	gs_entercontext(obs_graphics());

	effect_file = obs_find_plugin_file("test-input/test.effect");

	tf->source = source;
	tf->whatever = gs_create_effect_from_file(effect_file, NULL);
	bfree(effect_file);
	if (!tf->whatever) {
		test_destroy(tf);
		return NULL;
	}

	tf->texrender = texrender_create(GS_RGBA, GS_ZS_NONE);

	gs_leavecontext();

	return tf;
}
/* Run selftests.  */
static void
run_tests ()
{
  test_destroy ();
  test_release ();
}
Example #10
0
void run_tests() {
	Test *tests = test_init();
	test_runner(tests);
	test_destroy(tests);
}
Example #11
0
int main(int argc, char* argv[]) {
  int errors = 0;

  test_insert(&errors);
  test_lookup(&errors);
  test_present(&errors);
  test_remove(&errors);
  test_destroy(&errors);

  if (errors == 0)
    printf("All tests passed\n");
  else
    printf("\nTests done with %d error(s)\n", errors);

  if (argc >= 2) {
    /* Check for correct invocation: */
    if (argc != 2) {
      printf("Usage: %s <N>\n"
             "Run test inserting a total of N items\n", argv[0]);
      return 1;
    }
    int N = atoi(argv[1]);
    if (N <= 0 || N > kMaxInsertions) {
      N = kMaxInsertions;
    }

    /* Create the hash table. */
    hash_table* ht = hash_create(hash_fn, hash_strcmp);

    /* First phase: insert some data. */
    printf("\nInsert phase:\n");
    char* k;
    int64_t* v;
    char* removed_key = NULL;
    int64_t* removed_value = NULL;
    for (int i = 0; i < N * 2; i++) {
      k = (char*) malloc(kBufferLength);
      snprintf(k, kBufferLength, "String %d", i % N);
      v = (int64_t*) malloc(sizeof(int64_t));
      *v = i;
      // The hash map takes ownership of the key and value:
      hash_insert(ht, k, v, (void**) &removed_key, (void**) &removed_value);
      if (removed_value != NULL) {
        printf("Replaced (%s, %" PRIi64 ") while inserting (%s, %" PRIi64 ")\n",
               removed_key, *removed_value, k, *v);
        free(removed_key);
        free(removed_value);
      } else {
        printf("Inserted (%s, %" PRIi64 ")\n", k, *v);
      }
    }

    /* Second phase: look up some data. */
    printf("\nLookup phase:\n");
    char strbuf[kBufferLength];
    for (int i = N - 1; i >= 0; i--) {
      snprintf(strbuf, kBufferLength, "String %d", i);
      if (!hash_lookup(ht, strbuf, (void**) &v)) {
        printf("Entry for %s not found\n", strbuf);
      } else {
        printf("%s -> %" PRIi64 "\n", strbuf, *v);
      }
    }

    /* Look up a key that hasn't been inserted: */
    if (!hash_lookup(ht, kNotFoundKey, (void**) &v)) {
      printf("Lookup of \"%s\" failed (as expected)\n", kNotFoundKey);
    } else {
      printf("%s -> %" PRIi64 " (unexpected!)\n", kNotFoundKey, *v);
    }

    /* Destroy the hash table and free things that we've allocated. Because
     * we allocated both the keys and the values, we instruct the hash map
     * to free both.
     */
    hash_destroy(ht, true, true);
  }
  return 0;
}
Example #12
0
/**
 * Runs a single test.
 *
 * @param[in] filename
 * @param[in] cfg
 * @return A pointer to the instance of htp_connp_t created during
 *         the test, or NULL if the test failed for some reason.
 */
int test_run_ex(const char *testsdir, const char *testname, htp_cfg_t *cfg, htp_connp_t **connp, int clone_count) {
    char filename[1025];
    test_t test;
    struct timeval tv_start, tv_end;
    int rc;

    *connp = NULL;

    strncpy(filename, testsdir, 1024);
    strncat(filename, "/", 1024 - strlen(filename));
    strncat(filename, testname, 1024 - strlen(filename));

    // printf("Filename: %s\n", filename);

    // Initinialize test

    rc = test_init(&test, filename, clone_count);
    if (rc < 0) {
        return rc;
    }

    gettimeofday(&tv_start, NULL);

    test_start(&test);

    // Create parser
    *connp = htp_connp_create(cfg);
    if (*connp == NULL) {
        fprintf(stderr, "Failed to create connection parser\n");
        exit(1);
    }

    htp_connp_set_user_data(*connp, (void *) 0x02);

    // Does the filename contain connection metdata?
    if (strncmp(testname, "stream", 6) == 0) {
        // It does; use it
        char *remote_addr = NULL, *local_addr = NULL;
        int remote_port = -1, local_port = -1;

        parse_filename(testname, &remote_addr, &remote_port, &local_addr, &local_port);
        htp_connp_open(*connp, (const char *) remote_addr, remote_port, (const char *) local_addr, local_port, &tv_start);
        free(remote_addr);
        free(local_addr);
    } else {
        // No connection metadata; provide some fake information instead
        htp_connp_open(*connp, (const char *) "127.0.0.1", 10000, (const char *) "127.0.0.1", 80, &tv_start);
    }

    // Find all chunks and feed them to the parser
    int in_data_other = 0;
    char *in_data = NULL;
    size_t in_data_len = 0;
    size_t in_data_offset = 0;

    int out_data_other = 0;
    char *out_data = NULL;
    size_t out_data_len = 0;
    size_t out_data_offset = 0;

    for (;;) {
        if (test_next_chunk(&test) <= 0) {
            break;
        }

        if (test.chunk_direction == CLIENT) {
            if (in_data_other) {
                test_destroy(&test);
                fprintf(stderr, "Unable to buffer more than one inbound chunk.\n");
                return -1;
            }
            
            rc = htp_connp_req_data(*connp, &tv_start, test.chunk, test.chunk_len);
            if (rc == HTP_STREAM_ERROR) {
                test_destroy(&test);
                return -101;
            }
            if (rc == HTP_STREAM_DATA_OTHER) {
                // Parser needs to see the outbound stream in order to continue
                // parsing the inbound stream.
                in_data_other = 1;
                in_data = test.chunk;
                in_data_len = test.chunk_len;
                in_data_offset = htp_connp_req_data_consumed(*connp);                
            }
        } else {
            if (out_data_other) {
                rc = htp_connp_res_data(*connp, &tv_start, out_data + out_data_offset, out_data_len - out_data_offset);
                if (rc == HTP_STREAM_ERROR) {
                    test_destroy(&test);
                    return -104;
                }
                
                out_data_other = 0;
            }

            rc = htp_connp_res_data(*connp, &tv_start, test.chunk, test.chunk_len);
            if (rc == HTP_STREAM_ERROR) {
                test_destroy(&test);
                return -102;
            }
            if (rc == HTP_STREAM_DATA_OTHER) {
                // Parser needs to see the outbound stream in order to continue
                // parsing the inbound stream.
                out_data_other = 1;
                out_data = test.chunk;
                out_data_len = test.chunk_len;
                out_data_offset = htp_connp_res_data_consumed(*connp);
                // printf("# YYY out offset is %d\n", out_data_offset);
            }

            if (in_data_other) {
                rc = htp_connp_req_data(*connp, &tv_start, in_data + in_data_offset, in_data_len - in_data_offset);
                if (rc == HTP_STREAM_ERROR) {
                    test_destroy(&test);
                    return -103;
                }
                
                in_data_other = 0;
            }
        }
    }

    if (out_data_other) {
        rc = htp_connp_res_data(*connp, &tv_start, out_data + out_data_offset, out_data_len - out_data_offset);
        if (rc == HTP_STREAM_ERROR) {
            test_destroy(&test);
            return -104;
        }
        out_data_other = 0;
    }

    gettimeofday(&tv_end, NULL);

    // Close the connection
    htp_connp_close(*connp, &tv_end);

    // Clean up
    test_destroy(&test);

    return 1;
}
Example #13
0
static pj_status_t test_init(void)
{
    struct stream_cfg strm_cfg;
    pj_status_t status;

    /* Must init PJLIB first: */
    status = pj_init();
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);

    /* Must create a pool factory before we can allocate any memory. */
    pj_caching_pool_init(&g_app.cp, &pj_pool_factory_default_policy, 0);

    /* Pool */
    g_app.pool = pj_pool_create(&g_app.cp.factory, "g_app", 512, 512, NULL);

    /* Log file */
    if (g_app.cfg.log_file) {
	status = pj_file_open(g_app.pool, g_app.cfg.log_file, 
			      PJ_O_WRONLY,
			      &g_app.log_fd);
	if (status != PJ_SUCCESS) {
	    jbsim_perror("Error writing output file", status);
	    goto on_error;
	}

	pj_log_set_decor(PJ_LOG_HAS_SENDER | PJ_LOG_HAS_COLOR | PJ_LOG_HAS_LEVEL_TEXT);
	pj_log_set_log_func(&log_cb);
    }

    /* 
     * Initialize media endpoint.
     * This will implicitly initialize PJMEDIA too.
     */
    status = pjmedia_endpt_create(&g_app.cp.factory, NULL, 0, &g_app.endpt);
    if (status != PJ_SUCCESS) {
	jbsim_perror("Error creating media endpoint", status);
	goto on_error;
    }

    /* Register codecs */
    pjmedia_codec_register_audio_codecs(g_app.endpt, NULL);

    /* Create the loop transport */
    status = pjmedia_transport_loop_create(g_app.endpt, &g_app.loop);
    if (status != PJ_SUCCESS) {
	jbsim_perror("Error creating loop transport", status);
	goto on_error;
    }

    /* Create transmitter stream */
    pj_bzero(&strm_cfg, sizeof(strm_cfg));
    strm_cfg.name = "tx";
    strm_cfg.dir = PJMEDIA_DIR_ENCODING;
    strm_cfg.codec = g_app.cfg.codec;
    strm_cfg.ptime = g_app.cfg.tx_ptime;
    strm_cfg.dtx = g_app.cfg.tx_dtx;
    strm_cfg.plc = PJ_TRUE;
    status = stream_init(&strm_cfg, &g_app.tx);
    if (status != PJ_SUCCESS) 
	goto on_error;

    /* Create transmitter WAV */
    status = pjmedia_wav_player_port_create(g_app.pool, 
					    g_app.cfg.tx_wav_in,
					    g_app.cfg.tx_ptime,
					    0,
					    0,
					    &g_app.tx_wav);
    if (status != PJ_SUCCESS) {
	jbsim_perror("Error reading input WAV file", status);
	goto on_error;
    }

    /* Make sure stream and WAV parameters match */
    if (PJMEDIA_PIA_SRATE(&g_app.tx_wav->info) != PJMEDIA_PIA_SRATE(&g_app.tx->port->info) ||
	PJMEDIA_PIA_CCNT(&g_app.tx_wav->info) != PJMEDIA_PIA_CCNT(&g_app.tx->port->info))
    {
	jbsim_perror("Error: Input WAV file has different clock rate "
		     "or number of channels than the codec", PJ_SUCCESS);
	goto on_error;
    }


    /* Create receiver */
    pj_bzero(&strm_cfg, sizeof(strm_cfg));
    strm_cfg.name = "rx";
    strm_cfg.dir = PJMEDIA_DIR_DECODING;
    strm_cfg.codec = g_app.cfg.codec;
    strm_cfg.ptime = g_app.cfg.rx_ptime;
    strm_cfg.dtx = PJ_TRUE;
    strm_cfg.plc = g_app.cfg.rx_plc;
    status = stream_init(&strm_cfg, &g_app.rx);
    if (status != PJ_SUCCESS) 
	goto on_error;

    /* Create receiver WAV */
    status = pjmedia_wav_writer_port_create(g_app.pool, 
					    g_app.cfg.rx_wav_out,
					    PJMEDIA_PIA_SRATE(&g_app.rx->port->info),
					    PJMEDIA_PIA_CCNT(&g_app.rx->port->info),
					    PJMEDIA_PIA_SPF(&g_app.rx->port->info),
					    PJMEDIA_PIA_BITS(&g_app.rx->port->info),
					    0,
					    0,
					    &g_app.rx_wav);
    if (status != PJ_SUCCESS) {
	jbsim_perror("Error creating output WAV file", status);
	goto on_error;
    }


    /* Frame buffer */
    g_app.framebuf = (pj_int16_t*)
		     pj_pool_alloc(g_app.pool,
				   MAX(PJMEDIA_PIA_SPF(&g_app.rx->port->info),
				       PJMEDIA_PIA_SPF(&g_app.tx->port->info)) * sizeof(pj_int16_t));


    /* Set the receiver in the loop transport */
    pjmedia_transport_loop_disable_rx(g_app.loop, g_app.tx->strm, PJ_TRUE);

    /* Done */
    return PJ_SUCCESS;

on_error:
    test_destroy();
    return status;
}
Example #14
0
static pj_status_t test_init(void)
{
    struct stream_cfg strm_cfg;
    pj_status_t status;

    /* Must init PJLIB first: */
    status = pj_init();
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);

    /* Must create a pool factory before we can allocate any memory. */
    pj_caching_pool_init(&g_app.cp, &pj_pool_factory_default_policy, 0);

    /* Pool */
    g_app.pool = pj_pool_create(&g_app.cp.factory, "g_app", 512, 512, NULL);

    /* Log file */
    if (g_app.cfg.log_file) {
	status = pj_file_open(g_app.pool, g_app.cfg.log_file, 
			      PJ_O_WRONLY,
			      &g_app.log_fd);
	if (status != PJ_SUCCESS) {
	    jbsim_perror("Error writing output file", status);
	    goto on_error;
	}

	pj_log_set_decor(PJ_LOG_HAS_SENDER | PJ_LOG_HAS_COLOR | PJ_LOG_HAS_LEVEL_TEXT);
	pj_log_set_log_func(&log_cb);
    }

    /* 
     * Initialize media endpoint.
     * This will implicitly initialize PJMEDIA too.
     */
    status = pjmedia_endpt_create(&g_app.cp.factory, NULL, 0, &g_app.endpt);
    if (status != PJ_SUCCESS) {
	jbsim_perror("Error creating media endpoint", status);
	goto on_error;
    }

    /* Register codecs */
#if defined(PJMEDIA_HAS_GSM_CODEC) && PJMEDIA_HAS_GSM_CODEC != 0
    pjmedia_codec_gsm_init(g_app.endpt);
#endif
#if defined(PJMEDIA_HAS_G711_CODEC) && PJMEDIA_HAS_G711_CODEC!=0
    pjmedia_codec_g711_init(g_app.endpt);
#endif
#if defined(PJMEDIA_HAS_SPEEX_CODEC) && PJMEDIA_HAS_SPEEX_CODEC!=0
    pjmedia_codec_speex_init(g_app.endpt, 0, PJMEDIA_CODEC_SPEEX_DEFAULT_QUALITY,
			     PJMEDIA_CODEC_SPEEX_DEFAULT_COMPLEXITY);
#endif
#if defined(PJMEDIA_HAS_G722_CODEC) && (PJMEDIA_HAS_G722_CODEC != 0)
    pjmedia_codec_g722_init(g_app.endpt);
#endif
#if defined(PJMEDIA_HAS_ILBC_CODEC) && PJMEDIA_HAS_ILBC_CODEC != 0
    /* Init ILBC with mode=20 to make the losts occur at the same
     * places as other codecs.
     */
    pjmedia_codec_ilbc_init(g_app.endpt, 20);
#endif
#if defined(PJMEDIA_HAS_INTEL_IPP) && PJMEDIA_HAS_INTEL_IPP != 0
    pjmedia_codec_ipp_init(g_app.endpt);
#endif
#if defined(PJMEDIA_HAS_OPENCORE_AMRNB_CODEC) && (PJMEDIA_HAS_OPENCORE_AMRNB_CODEC != 0)
    pjmedia_codec_opencore_amrnb_init(g_app.endpt);
#endif
#if defined(PJMEDIA_HAS_L16_CODEC) && PJMEDIA_HAS_L16_CODEC != 0
    pjmedia_codec_l16_init(g_app.endpt, 0);
#endif

    /* Create the loop transport */
    status = pjmedia_transport_loop_create(g_app.endpt, &g_app.loop);
    if (status != PJ_SUCCESS) {
	jbsim_perror("Error creating loop transport", status);
	goto on_error;
    }

    /* Create transmitter stream */
    pj_bzero(&strm_cfg, sizeof(strm_cfg));
    strm_cfg.name = "tx";
    strm_cfg.dir = PJMEDIA_DIR_ENCODING;
    strm_cfg.codec = g_app.cfg.codec;
    strm_cfg.ptime = g_app.cfg.tx_ptime;
    strm_cfg.dtx = g_app.cfg.tx_dtx;
    strm_cfg.plc = PJ_TRUE;
    status = stream_init(&strm_cfg, &g_app.tx);
    if (status != PJ_SUCCESS) 
	goto on_error;

    /* Create transmitter WAV */
    status = pjmedia_wav_player_port_create(g_app.pool, 
					    g_app.cfg.tx_wav_in,
					    g_app.cfg.tx_ptime,
					    0,
					    0,
					    &g_app.tx_wav);
    if (status != PJ_SUCCESS) {
	jbsim_perror("Error reading input WAV file", status);
	goto on_error;
    }

    /* Make sure stream and WAV parameters match */
    if (g_app.tx_wav->info.clock_rate != g_app.tx->port->info.clock_rate ||
	g_app.tx_wav->info.channel_count != g_app.tx->port->info.channel_count)
    {
	jbsim_perror("Error: Input WAV file has different clock rate "
		     "or number of channels than the codec", PJ_SUCCESS);
	goto on_error;
    }


    /* Create receiver */
    pj_bzero(&strm_cfg, sizeof(strm_cfg));
    strm_cfg.name = "rx";
    strm_cfg.dir = PJMEDIA_DIR_DECODING;
    strm_cfg.codec = g_app.cfg.codec;
    strm_cfg.ptime = g_app.cfg.rx_ptime;
    strm_cfg.dtx = PJ_TRUE;
    strm_cfg.plc = g_app.cfg.rx_plc;
    status = stream_init(&strm_cfg, &g_app.rx);
    if (status != PJ_SUCCESS) 
	goto on_error;

    /* Create receiver WAV */
    status = pjmedia_wav_writer_port_create(g_app.pool, 
					    g_app.cfg.rx_wav_out,
					    g_app.rx->port->info.clock_rate,
					    g_app.rx->port->info.channel_count,
					    g_app.rx->port->info.samples_per_frame,
					    g_app.rx->port->info.bits_per_sample,
					    0,
					    0,
					    &g_app.rx_wav);
    if (status != PJ_SUCCESS) {
	jbsim_perror("Error creating output WAV file", status);
	goto on_error;
    }


    /* Frame buffer */
    g_app.framebuf = (pj_int16_t*)
		     pj_pool_alloc(g_app.pool,
				   MAX(g_app.rx->port->info.samples_per_frame,
				       g_app.tx->port->info.samples_per_frame) * sizeof(pj_int16_t));


    /* Set the receiver in the loop transport */
    pjmedia_transport_loop_disable_rx(g_app.loop, g_app.tx->strm, PJ_TRUE);

    /* Done */
    return PJ_SUCCESS;

on_error:
    test_destroy();
    return status;
}