PJ_DEF(void) pjsua_dump(pj_bool_t detail)
{
    unsigned old_decor;
    unsigned i;

    PJ_LOG(3,(THIS_FILE, "Start dumping application states:"));

    old_decor = pj_log_get_decor();
    pj_log_set_decor(old_decor & (PJ_LOG_HAS_NEWLINE | PJ_LOG_HAS_CR));

    if (detail)
	pj_dump_config();

    pjsip_endpt_dump(pjsua_get_pjsip_endpt(), detail);

    pjmedia_endpt_dump(pjsua_get_pjmedia_endpt());

    PJ_LOG(3,(THIS_FILE, "Dumping media transports:"));
    for (i=0; i<pjsua_var.ua_cfg.max_calls; ++i) {
	pjsua_call *call = &pjsua_var.calls[i];
	pjsua_acc_config *acc_cfg;
	pjmedia_transport *tp[PJSUA_MAX_CALL_MEDIA*2];
	unsigned tp_cnt = 0;
	unsigned j;

	/* Collect media transports in this call */
	for (j = 0; j < call->med_cnt; ++j) {
	    if (call->media[j].tp != NULL)
		tp[tp_cnt++] = call->media[j].tp;
	}
	for (j = 0; j < call->med_prov_cnt; ++j) {
	    pjmedia_transport *med_tp = call->media_prov[j].tp;
	    if (med_tp) {
		unsigned k;
		pj_bool_t used = PJ_FALSE;
		for (k = 0; k < tp_cnt; ++k) {
		    if (med_tp == tp[k]) {
			used = PJ_TRUE;
			break;
		    }
		}
		if (!used)
		    tp[tp_cnt++] = med_tp;
	    }
	}

	acc_cfg = &pjsua_var.acc[call->acc_id].cfg;

	/* Dump the media transports in this call */
	for (j = 0; j < tp_cnt; ++j) {
	    pjmedia_transport_info tpinfo;
	    char addr_buf[80];

	    pjmedia_transport_info_init(&tpinfo);
	    pjmedia_transport_get_info(tp[j], &tpinfo);
	    PJ_LOG(3,(THIS_FILE, " %s: %s",
		      (acc_cfg->ice_cfg.enable_ice ? "ICE" : "UDP"),
		      pj_sockaddr_print(&tpinfo.sock_info.rtp_addr_name,
					addr_buf,
					sizeof(addr_buf), 3)));
	}
    }

    pjsip_tsx_layer_dump(detail);
    pjsip_ua_dump(detail);

// Dumping complete call states may require a 'large' buffer 
// (about 3KB per call session, including RTCP XR).
#if 0
    /* Dump all invite sessions: */
    PJ_LOG(3,(THIS_FILE, "Dumping invite sessions:"));

    if (pjsua_call_get_count() == 0) {

	PJ_LOG(3,(THIS_FILE, "  - no sessions -"));

    } else {
	unsigned i;

	for (i=0; i<pjsua_var.ua_cfg.max_calls; ++i) {
	    if (pjsua_call_is_active(i)) {
		/* Tricky logging, since call states log string tends to be 
		 * longer than PJ_LOG_MAX_SIZE.
		 */
		char buf[1024 * 3];
		unsigned call_dump_len;
		unsigned part_len;
		unsigned part_idx;
		unsigned log_decor;

		pjsua_call_dump(i, detail, buf, sizeof(buf), "  ");
		call_dump_len = strlen(buf);

		log_decor = pj_log_get_decor();
		pj_log_set_decor(log_decor & ~(PJ_LOG_HAS_NEWLINE | 
					       PJ_LOG_HAS_CR));
		PJ_LOG(3,(THIS_FILE, "\n"));
		pj_log_set_decor(0);

		part_idx = 0;
		part_len = PJ_LOG_MAX_SIZE-80;
		while (part_idx < call_dump_len) {
		    char p_orig, *p;

		    p = &buf[part_idx];
		    if (part_idx + part_len > call_dump_len)
			part_len = call_dump_len - part_idx;
		    p_orig = p[part_len];
		    p[part_len] = '\0';
		    PJ_LOG(3,(THIS_FILE, "%s", p));
		    p[part_len] = p_orig;
		    part_idx += part_len;
		}
		pj_log_set_decor(log_decor);
	    }
	}
    }
#endif

    /* Dump presence status */
    pjsua_pres_dump(detail);

    pj_log_set_decor(old_decor);
    PJ_LOG(3,(THIS_FILE, "Dump complete"));
}
PJ_DEF(void) pjsua_dump(pj_bool_t detail)
{
    unsigned old_decor;
    unsigned i;

    PJ_LOG(3,(THIS_FILE, "Start dumping application states:"));

    old_decor = pj_log_get_decor();
    pj_log_set_decor(old_decor & (PJ_LOG_HAS_NEWLINE | PJ_LOG_HAS_CR));

    if (detail)
	pj_dump_config();

    pjsip_endpt_dump(pjsua_get_pjsip_endpt(), detail);

    pjmedia_endpt_dump(pjsua_get_pjmedia_endpt());

    PJ_LOG(3,(THIS_FILE, "Dumping media transports:"));
    for (i=0; i<pjsua_var.ua_cfg.max_calls; ++i) {
	pjsua_call *call = &pjsua_var.calls[i];
	pjsua_acc_config *acc_cfg;
	pjmedia_transport *tp[PJSUA_MAX_CALL_MEDIA*2];
	unsigned tp_cnt = 0;
	unsigned j;

	 
	for (j = 0; j < call->med_cnt; ++j) {
	    if (call->media[j].tp != NULL)
		tp[tp_cnt++] = call->media[j].tp;
	}
	for (j = 0; j < call->med_prov_cnt; ++j) {
	    pjmedia_transport *med_tp = call->media_prov[j].tp;
	    if (med_tp) {
		unsigned k;
		pj_bool_t used = PJ_FALSE;
		for (k = 0; k < tp_cnt; ++k) {
		    if (med_tp == tp[k]) {
			used = PJ_TRUE;
			break;
		    }
		}
		if (!used)
		    tp[tp_cnt++] = med_tp;
	    }
	}

	acc_cfg = &pjsua_var.acc[call->acc_id].cfg;

	 
	for (j = 0; j < tp_cnt; ++j) {
	    pjmedia_transport_info tpinfo;
	    char addr_buf[80];

	    pjmedia_transport_info_init(&tpinfo);
	    pjmedia_transport_get_info(tp[j], &tpinfo);
	    PJ_LOG(3,(THIS_FILE, " %s: %s",
		      (acc_cfg->ice_cfg.enable_ice ? "ICE" : "UDP"),
		      pj_sockaddr_print(&tpinfo.sock_info.rtp_addr_name,
					addr_buf,
					sizeof(addr_buf), 3)));
	}
    }

    pjsip_tsx_layer_dump(detail);
    pjsip_ua_dump(detail);

 
 
#if 0
     
    PJ_LOG(3,(THIS_FILE, "Dumping invite sessions:"));

    if (pjsua_call_get_count() == 0) {

	PJ_LOG(3,(THIS_FILE, "  - no sessions -"));

    } else {
	unsigned i;

	for (i=0; i<pjsua_var.ua_cfg.max_calls; ++i) {
	    if (pjsua_call_is_active(i)) {
		 
		char buf[1024 * 3];
		unsigned call_dump_len;
		unsigned part_len;
		unsigned part_idx;
		unsigned log_decor;

		pjsua_call_dump(i, detail, buf, sizeof(buf), "  ");
		call_dump_len = strlen(buf);

		log_decor = pj_log_get_decor();
		pj_log_set_decor(log_decor & ~(PJ_LOG_HAS_NEWLINE | 
					       PJ_LOG_HAS_CR));
		PJ_LOG(3,(THIS_FILE, "\n"));
		pj_log_set_decor(0);

		part_idx = 0;
		part_len = PJ_LOG_MAX_SIZE-80;
		while (part_idx < call_dump_len) {
		    char p_orig, *p;

		    p = &buf[part_idx];
		    if (part_idx + part_len > call_dump_len)
			part_len = call_dump_len - part_idx;
		    p_orig = p[part_len];
		    p[part_len] = '\0';
		    PJ_LOG(3,(THIS_FILE, "%s", p));
		    p[part_len] = p_orig;
		    part_idx += part_len;
		}
		pj_log_set_decor(log_decor);
	    }
	}
    }
#endif

     
    pjsua_pres_dump(detail);

    pj_log_set_decor(old_decor);
    PJ_LOG(3,(THIS_FILE, "Dump complete"));
}