PJ_DEF(pj_status_t) pjsua_create(void)
{
    pj_status_t status;

    /* Init pjsua data */
    init_data();

    /* Set default logging settings */
    pjsua_logging_config_default(&pjsua_var.log_cfg);

    /* Init PJLIB: */
    status = pj_init();
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);

    pj_log_push_indent();

    /* Init random seed */
    init_random_seed();

    /* Init PJLIB-UTIL: */
    status = pjlib_util_init();
    if (status != PJ_SUCCESS) {
	pj_log_pop_indent();
	pjsua_perror(THIS_FILE, "Failed in initializing pjlib-util", status);
	pj_shutdown();
	return status;
    }

    /* Init PJNATH */
    status = pjnath_init();
    if (status != PJ_SUCCESS) {
	pj_log_pop_indent();
	pjsua_perror(THIS_FILE, "Failed in initializing pjnath", status);
	pj_shutdown();
	return status;
    }

    /* Set default sound device ID */
    pjsua_var.cap_dev = PJMEDIA_AUD_DEFAULT_CAPTURE_DEV;
    pjsua_var.play_dev = PJMEDIA_AUD_DEFAULT_PLAYBACK_DEV;

    /* Set default video device ID */
    pjsua_var.vcap_dev = PJMEDIA_VID_DEFAULT_CAPTURE_DEV;
    pjsua_var.vrdr_dev = PJMEDIA_VID_DEFAULT_RENDER_DEV;

    /* Init caching pool. */
    pj_caching_pool_init(&pjsua_var.cp, NULL, 0);

    /* Create memory pools for application and internal use. */
    pjsua_var.pool = pjsua_pool_create("pjsua", PJSUA_POOL_LEN, PJSUA_POOL_INC);
    pjsua_var.timer_pool = pjsua_pool_create("pjsua_timer", 500, 500);
    if (pjsua_var.pool == NULL || pjsua_var.timer_pool == NULL) {
	pj_log_pop_indent();
	status = PJ_ENOMEM;
	pjsua_perror(THIS_FILE, "Unable to create pjsua/timer pool", status);
	pj_shutdown();
	return status;
    }
    
    /* Create mutex */
    status = pj_mutex_create_recursive(pjsua_var.pool, "pjsua", 
				       &pjsua_var.mutex);
    if (status != PJ_SUCCESS) {
	pj_log_pop_indent();
	pjsua_perror(THIS_FILE, "Unable to create mutex", status);
	pjsua_destroy();
	return status;
    }

    /* Must create SIP endpoint to initialize SIP parser. The parser
     * is needed for example when application needs to call pjsua_verify_url().
     */
    status = pjsip_endpt_create(&pjsua_var.cp.factory, 
				pj_gethostname()->ptr, 
				&pjsua_var.endpt);
    if (status != PJ_SUCCESS) {
	pj_log_pop_indent();
	pjsua_perror(THIS_FILE, "Unable to create endpoint", status);
	pjsua_destroy();
	return status;
    }

    /* Init timer entry and event list */
    pj_list_init(&pjsua_var.active_timer_list);
    pj_list_init(&pjsua_var.timer_list);
    pj_list_init(&pjsua_var.event_list);

    /* Create timer mutex */
    status = pj_mutex_create_recursive(pjsua_var.pool, "pjsua_timer", 
				       &pjsua_var.timer_mutex);
    if (status != PJ_SUCCESS) {
	pj_log_pop_indent();
	pjsua_perror(THIS_FILE, "Unable to create mutex", status);
	pjsua_destroy();
	return status;
    }

    pjsua_set_state(PJSUA_STATE_CREATED);
    pj_log_pop_indent();
    return PJ_SUCCESS;
}
PJ_DEF(pj_status_t) pjsua_create(void)
{
    pj_status_t status;

     
    init_data();

     
    pjsua_logging_config_default(&pjsua_var.log_cfg);

     
    status = pj_init();
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);

    pj_log_push_indent();

     
    init_random_seed();

     
    status = pjlib_util_init();
    if (status != PJ_SUCCESS) {
	pj_log_pop_indent();
	pjsua_perror(THIS_FILE, "Failed in initializing pjlib-util", status);
	pj_shutdown();
	return status;
    }

     
    status = pjnath_init();
    if (status != PJ_SUCCESS) {
	pj_log_pop_indent();
	pjsua_perror(THIS_FILE, "Failed in initializing pjnath", status);
	pj_shutdown();
	return status;
    }

     
    pjsua_var.cap_dev = PJMEDIA_AUD_DEFAULT_CAPTURE_DEV;
    pjsua_var.play_dev = PJMEDIA_AUD_DEFAULT_PLAYBACK_DEV;

     
    pjsua_var.vcap_dev = PJMEDIA_VID_DEFAULT_CAPTURE_DEV;
    pjsua_var.vrdr_dev = PJMEDIA_VID_DEFAULT_RENDER_DEV;

     
    pj_caching_pool_init(&pjsua_var.cp, NULL, 0);

     
    pjsua_var.pool = pjsua_pool_create("pjsua", PJSUA_POOL_LEN, PJSUA_POOL_INC);
    pjsua_var.timer_pool = pjsua_pool_create("pjsua_timer", 500, 500);
    if (pjsua_var.pool == NULL || pjsua_var.timer_pool == NULL) {
	pj_log_pop_indent();
	status = PJ_ENOMEM;
	pjsua_perror(THIS_FILE, "Unable to create pjsua/timer pool", status);
	pj_shutdown();
	return status;
    }
    
     
    status = pj_mutex_create_recursive(pjsua_var.pool, "pjsua", 
				       &pjsua_var.mutex);
    if (status != PJ_SUCCESS) {
	pj_log_pop_indent();
	pjsua_perror(THIS_FILE, "Unable to create mutex", status);
	pjsua_destroy();
	return status;
    }

     
    status = pjsip_endpt_create(&pjsua_var.cp.factory, 
				pj_gethostname()->ptr, 
				&pjsua_var.endpt);
    if (status != PJ_SUCCESS) {
	pj_log_pop_indent();
	pjsua_perror(THIS_FILE, "Unable to create endpoint", status);
	pjsua_destroy();
	return status;
    }

     
    pj_list_init(&pjsua_var.active_timer_list);
    pj_list_init(&pjsua_var.timer_list);
    pj_list_init(&pjsua_var.event_list);

     
    status = pj_mutex_create_recursive(pjsua_var.pool, "pjsua_timer", 
				       &pjsua_var.timer_mutex);
    if (status != PJ_SUCCESS) {
	pj_log_pop_indent();
	pjsua_perror(THIS_FILE, "Unable to create mutex", status);
	pjsua_destroy();
	return status;
    }

    pjsua_set_state(PJSUA_STATE_CREATED);
    pj_log_pop_indent();
    return PJ_SUCCESS;
}