summaryrefslogtreecommitdiff
path: root/pjsip
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2006-06-01 12:28:44 +0000
committerBenny Prijono <bennylp@teluu.com>2006-06-01 12:28:44 +0000
commit45edf54f6aaf54adb7b42f786b60cd3f23d9be2f (patch)
tree1c92f4947159c5b431e0a9cb696ab0a01d20a234 /pjsip
parentad70abbdad70cbc5e0c61b41531783290fe08f48 (diff)
Initial work on pjsua ActiveX component
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@487 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjsip')
-rw-r--r--pjsip/include/pjsua-lib/pjsua.h31
-rw-r--r--pjsip/include/pjsua-lib/pjsua_console_app.h3
-rw-r--r--pjsip/src/pjsua-lib/pjsua_console_app.c57
-rw-r--r--pjsip/src/pjsua-lib/pjsua_core.c121
-rw-r--r--pjsip/src/pjsua-lib/pjsua_imp.h3
-rw-r--r--pjsip/src/pjsua-lib/pjsua_pres.c13
-rw-r--r--pjsip/src/pjsua-lib/pjsua_reg.c10
-rw-r--r--pjsip/src/pjsua-lib/pjsua_settings.c244
8 files changed, 308 insertions, 174 deletions
diff --git a/pjsip/include/pjsua-lib/pjsua.h b/pjsip/include/pjsua-lib/pjsua.h
index cb2e8b7a..622991f6 100644
--- a/pjsip/include/pjsua-lib/pjsua.h
+++ b/pjsip/include/pjsua-lib/pjsua.h
@@ -143,9 +143,15 @@ struct pjsua_config
*/
unsigned conf_ports;
- /** Number of worker threads (default: 1) */
+ /** Number of worker threads (value >=0, default: 1) */
unsigned thread_cnt;
+ /** Separate ioqueue for media? (default: yes) */
+ pj_bool_t media_has_ioqueue;
+
+ /** Number of worker thread for media (value >=0, default: 1) */
+ unsigned media_thread_cnt;
+
/** First STUN server IP address. When STUN is configured, then the
* two STUN server settings must be fully set.
* (default: none)
@@ -359,6 +365,7 @@ struct pjsua_buddy_info
pjsua_buddy_status status;
pj_str_t status_text;
pj_bool_t monitor;
+ int acc_index;
};
typedef struct pjsua_buddy_info pjsua_buddy_info;
@@ -439,6 +446,12 @@ PJ_DECL(pj_status_t) pjsua_start(void);
PJ_DECL(pj_status_t) pjsua_destroy(void);
/**
+ * Poll pjsua.
+ */
+PJ_DECL(int) pjsua_handle_events(unsigned msec_timeout);
+
+
+/**
* Get SIP endpoint instance.
* Only valid after pjsua_init().
*/
@@ -560,6 +573,14 @@ PJ_DECL(void) pjsua_call_typing(int call_index, pj_bool_t is_typing);
PJ_DECL(void) pjsua_call_hangup_all(void);
+/**
+ * Dump call and media statistics to string.
+ */
+PJ_DECL(void) pjsua_dump_call(int call_index, int with_media,
+ char *buffer, unsigned maxlen,
+ const char *indent);
+
+
/*****************************************************************************
* PJSUA Account and Client Registration API (defined in pjsua_reg.c).
*/
@@ -598,7 +619,7 @@ PJ_DECL(pj_status_t) pjsua_acc_set_online_status(unsigned acc_index,
* Update registration or perform unregistration. If renew argument is zero,
* this will start unregistration process.
*/
-PJ_DECL(void) pjsua_acc_set_registration(unsigned acc_index, pj_bool_t renew);
+PJ_DECL(pj_status_t) pjsua_acc_set_registration(unsigned acc_index, pj_bool_t renew);
@@ -637,7 +658,7 @@ PJ_DECL(pj_status_t) pjsua_buddy_subscribe_pres(unsigned buddy_index,
/**
* Refresh both presence client and server subscriptions.
*/
-PJ_DECL(void) pjsua_pres_refresh(int acc_index);
+PJ_DECL(void) pjsua_pres_refresh(void);
/**
* Dump presence subscriptions.
@@ -712,7 +733,7 @@ PJ_DECL(pj_status_t) pjsua_player_create(const pj_str_t *filename,
/**
* Get conference port associated with player.
*/
-PJ_DECL(unsigned) pjsua_player_get_conf_port(pjsua_player_id id);
+PJ_DECL(int) pjsua_player_get_conf_port(pjsua_player_id id);
/**
@@ -739,7 +760,7 @@ PJ_DECL(pj_status_t) pjsua_recorder_create(const pj_str_t *filename,
/**
* Get conference port associated with recorder.
*/
-PJ_DECL(unsigned) pjsua_recorder_get_conf_port(pjsua_recorder_id id);
+PJ_DECL(int) pjsua_recorder_get_conf_port(pjsua_recorder_id id);
/**
diff --git a/pjsip/include/pjsua-lib/pjsua_console_app.h b/pjsip/include/pjsua-lib/pjsua_console_app.h
index 058d0637..ee7213ed 100644
--- a/pjsip/include/pjsua-lib/pjsua_console_app.h
+++ b/pjsip/include/pjsua-lib/pjsua_console_app.h
@@ -20,9 +20,6 @@
#define __PJSUA_CONSOLE_APP_H__
-pj_status_t pjsua_console_app_logging_init(const pjsua_config *cfg);
-void pjsua_console_app_logging_shutdown(void);
-
void pjsua_console_app_main(void);
extern pjsip_module pjsua_console_app_msg_logger;
diff --git a/pjsip/src/pjsua-lib/pjsua_console_app.c b/pjsip/src/pjsua-lib/pjsua_console_app.c
index 62069b9a..58f64c7f 100644
--- a/pjsip/src/pjsua-lib/pjsua_console_app.c
+++ b/pjsip/src/pjsua-lib/pjsua_console_app.c
@@ -781,7 +781,7 @@ void pjsua_console_app_main(void)
pjsua_buddy_subscribe_pres(result.nb_result-1, (menuin[0]=='s'));
}
- pjsua_pres_refresh(current_acc);
+ pjsua_pres_refresh();
} else if (result.uri_result) {
puts("Sorry, can only subscribe to buddy's presence, "
@@ -814,7 +814,7 @@ void pjsua_console_app_main(void)
printf("Setting %s online status to %s\n",
acc_info.acc_id.ptr,
(acc_info.online_status?"online":"offline"));
- pjsua_pres_refresh(current_acc);
+ pjsua_pres_refresh();
break;
case 'c':
@@ -971,59 +971,6 @@ pjsip_module pjsua_console_app_msg_logger =
/*****************************************************************************
- * Console application custom logging:
- */
-
-
-static FILE *log_file;
-
-
-static void app_log_writer(int level, const char *buffer, int len)
-{
- /* Write to both stdout and file. */
-
- if (level <= (int)pjsua_get_config()->app_log_level)
- pj_log_write(level, buffer, len);
-
- if (log_file) {
- fwrite(buffer, len, 1, log_file);
- fflush(log_file);
- }
-}
-
-
-pj_status_t pjsua_console_app_logging_init(const pjsua_config *cfg)
-{
- /* Redirect log function to ours */
-
- pj_log_set_log_func( &app_log_writer );
-
- /* If output log file is desired, create the file: */
-
- if (cfg->log_filename.slen) {
- log_file = fopen(cfg->log_filename.ptr, "wt");
- if (log_file == NULL) {
- PJ_LOG(1,(THIS_FILE, "Unable to open log file %s",
- cfg->log_filename.ptr));
- return -1;
- }
- }
-
- return PJ_SUCCESS;
-}
-
-
-void pjsua_console_app_logging_shutdown(void)
-{
- /* Close logging file, if any: */
-
- if (log_file) {
- fclose(log_file);
- log_file = NULL;
- }
-}
-
-/*****************************************************************************
* Error display:
*/
diff --git a/pjsip/src/pjsua-lib/pjsua_core.c b/pjsip/src/pjsua-lib/pjsua_core.c
index 3ec5947f..3f63ce8f 100644
--- a/pjsip/src/pjsua-lib/pjsua_core.c
+++ b/pjsip/src/pjsua-lib/pjsua_core.c
@@ -51,6 +51,8 @@ PJ_DEF(void) pjsua_default_config(pjsua_config *cfg)
pj_memset(cfg, 0, sizeof(pjsua_config));
cfg->thread_cnt = 1;
+ cfg->media_has_ioqueue = 1;
+ cfg->media_thread_cnt = 1;
cfg->udp_port = 5060;
cfg->start_rtp_port = 4000;
cfg->max_calls = 4;
@@ -246,6 +248,25 @@ static int PJ_THREAD_FUNC pjsua_poll(void *arg)
return 0;
}
+/**
+ * Poll pjsua.
+ */
+PJ_DECL(int) pjsua_handle_events(unsigned msec_timeout)
+{
+ unsigned count = 0;
+ pj_time_val tv;
+ pj_status_t status;
+
+ tv.sec = 0;
+ tv.msec = msec_timeout;
+ pj_time_val_normalize(&tv);
+
+ status = pjsip_endpt_handle_events2(pjsua.endpt, &tv, &count);
+ if (status != PJ_SUCCESS)
+ return -status;
+
+ return count;
+}
#define pjsua_has_stun() (pjsua.config.stun_port1 && \
@@ -504,7 +525,9 @@ PJ_DEF(pj_status_t) pjsua_create(void)
/* Must create media endpoint too */
status = pjmedia_endpt_create(&pjsua.cp.factory,
- pjsip_endpt_get_ioqueue(pjsua.endpt), 0,
+ pjsua.config.media_has_ioqueue? NULL :
+ pjsip_endpt_get_ioqueue(pjsua.endpt),
+ pjsua.config.media_thread_cnt,
&pjsua.med_endpt);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE,
@@ -754,6 +777,57 @@ static void copy_config(pj_pool_t *pool, pjsua_config *dst,
}
+/*****************************************************************************
+ * Console application custom logging:
+ */
+
+
+static void log_writer(int level, const char *buffer, int len)
+{
+ /* Write to both stdout and file. */
+
+ if (level <= (int)pjsua.config.app_log_level)
+ pj_log_write(level, buffer, len);
+
+ if (pjsua.log_file) {
+ fwrite(buffer, len, 1, pjsua.log_file);
+ fflush(pjsua.log_file);
+ }
+}
+
+
+static pj_status_t logging_init()
+{
+ /* Redirect log function to ours */
+
+ pj_log_set_log_func( &log_writer );
+
+ /* If output log file is desired, create the file: */
+
+ if (pjsua.config.log_filename.slen) {
+ pjsua.log_file = fopen(pjsua.config.log_filename.ptr, "wt");
+ if (pjsua.log_file == NULL) {
+ PJ_LOG(1,(THIS_FILE, "Unable to open log file %s",
+ pjsua.config.log_filename.ptr));
+ return -1;
+ }
+ }
+
+ return PJ_SUCCESS;
+}
+
+
+static void logging_shutdown(void)
+{
+ /* Close logging file, if any: */
+
+ if (pjsua.log_file) {
+ fclose(pjsua.log_file);
+ pjsua.log_file = NULL;
+ }
+}
+
+
/*
* Initialize pjsua application.
* This will initialize all libraries, create endpoint instance, and register
@@ -807,6 +881,10 @@ PJ_DECL(pj_status_t) pjsua_init(const pjsua_config *cfg,
pj_log_set_level(pjsua.config.log_level);
pj_log_set_decor(pjsua.config.log_decor);
+ status = logging_init();
+ if (status != PJ_SUCCESS)
+ goto on_error;
+
/* Create SIP UDP socket */
if (pjsua.config.udp_port) {
@@ -853,7 +931,7 @@ PJ_DECL(pj_status_t) pjsua_init(const pjsua_config *cfg,
goto on_error;
}
status = pjmedia_transport_udp_attach(pjsua.med_endpt, NULL,
- &pjsua.calls[i].skinfo,
+ &pjsua.calls[i].skinfo, 0,
&pjsua.calls[i].med_tp);
}
@@ -1368,7 +1446,7 @@ PJ_DEF(pj_status_t) pjsua_player_create( const pj_str_t *filename,
/**
* Get conference port associated with player.
*/
-PJ_DEF(unsigned) pjsua_player_get_conf_port(pjsua_player_id id)
+PJ_DEF(int) pjsua_player_get_conf_port(pjsua_player_id id)
{
PJ_ASSERT_RETURN(id>=0 && id < PJ_ARRAY_SIZE(pjsua.player), PJ_EINVAL);
return pjsua.player[id].slot;
@@ -1452,7 +1530,7 @@ PJ_DEF(pj_status_t) pjsua_recorder_create( const pj_str_t *filename,
/**
* Get conference port associated with recorder.
*/
-PJ_DEF(unsigned) pjsua_recorder_get_conf_port(pjsua_recorder_id id)
+PJ_DEF(int) pjsua_recorder_get_conf_port(pjsua_recorder_id id)
{
PJ_ASSERT_RETURN(id>=0 && id < PJ_ARRAY_SIZE(pjsua.recorder), PJ_EINVAL);
return pjsua.recorder[id].slot;
@@ -1521,19 +1599,6 @@ PJ_DEF(pj_status_t) pjsua_destroy(void)
/* Signal threads to quit: */
pjsua.quit_flag = 1;
- /* Terminate all calls. */
- pjsua_call_hangup_all();
-
- /* Terminate all presence subscriptions. */
- pjsua_pres_shutdown();
-
- /* Unregister, if required: */
- for (i=0; i<(int)pjsua.config.acc_cnt; ++i) {
- if (pjsua.acc[i].regc) {
- pjsua_acc_set_registration(i, PJ_FALSE);
- }
- }
-
/* Wait worker threads to quit: */
for (i=0; i<(int)pjsua.config.thread_cnt; ++i) {
@@ -1544,9 +1609,22 @@ PJ_DEF(pj_status_t) pjsua_destroy(void)
}
}
-
- /* Wait for some time to allow unregistration to complete: */
+
if (pjsua.endpt) {
+ /* Terminate all calls. */
+ pjsua_call_hangup_all();
+
+ /* Terminate all presence subscriptions. */
+ pjsua_pres_shutdown();
+
+ /* Unregister, if required: */
+ for (i=0; i<(int)pjsua.config.acc_cnt; ++i) {
+ if (pjsua.acc[i].regc) {
+ pjsua_acc_set_registration(i, PJ_FALSE);
+ }
+ }
+
+ /* Wait for some time to allow unregistration to complete: */
PJ_LOG(4,(THIS_FILE, "Shutting down..."));
busy_sleep(1000);
}
@@ -1629,6 +1707,11 @@ PJ_DEF(pj_status_t) pjsua_destroy(void)
pj_caching_pool_destroy(&pjsua.cp);
+ PJ_LOG(4,(THIS_FILE, "PJSUA destroyed..."));
+
+ /* End logging */
+ logging_shutdown();
+
/* Done. */
return PJ_SUCCESS;
diff --git a/pjsip/src/pjsua-lib/pjsua_imp.h b/pjsip/src/pjsua-lib/pjsua_imp.h
index 208c999d..ec1918d3 100644
--- a/pjsip/src/pjsua-lib/pjsua_imp.h
+++ b/pjsip/src/pjsua-lib/pjsua_imp.h
@@ -126,6 +126,9 @@ struct pjsua
/* Config: */
pjsua_config config; /**< PJSUA configs */
+ /* Log file: */
+ FILE *log_file; /**< Log file. */
+
/* Application callback
: */
pjsua_callback cb; /**< Application callback. */
diff --git a/pjsip/src/pjsua-lib/pjsua_pres.c b/pjsip/src/pjsua-lib/pjsua_pres.c
index fe6eedce..c76d3cbb 100644
--- a/pjsip/src/pjsua-lib/pjsua_pres.c
+++ b/pjsip/src/pjsua-lib/pjsua_pres.c
@@ -471,6 +471,7 @@ PJ_DEF(pj_status_t) pjsua_buddy_get_info(unsigned index,
info->status_text = pj_str("Offline");
}
+ info->acc_index = buddy->acc_index;
return PJ_SUCCESS;
}
@@ -549,10 +550,14 @@ PJ_DEF(pj_status_t) pjsua_acc_set_online_status( unsigned acc_index,
/*
* Refresh presence
*/
-PJ_DEF(void) pjsua_pres_refresh(int acc_index)
+PJ_DEF(void) pjsua_pres_refresh()
{
+ unsigned i;
+
refresh_client_subscription();
- refresh_server_subscription(acc_index);
+
+ for (i=0; i<PJ_ARRAY_SIZE(pjsua.acc); ++i)
+ refresh_server_subscription(i);
}
@@ -572,9 +577,7 @@ void pjsua_pres_shutdown(void)
pjsua.buddies[i].monitor = 0;
}
- for (acc_index=0; acc_index<(int)pjsua.config.acc_cnt; ++acc_index) {
- pjsua_pres_refresh(acc_index);
- }
+ pjsua_pres_refresh();
}
/*
diff --git a/pjsip/src/pjsua-lib/pjsua_reg.c b/pjsip/src/pjsua-lib/pjsua_reg.c
index 3774740a..f85bcd77 100644
--- a/pjsip/src/pjsua-lib/pjsua_reg.c
+++ b/pjsip/src/pjsua-lib/pjsua_reg.c
@@ -132,7 +132,7 @@ PJ_DEF(pj_status_t) pjsua_acc_get_info( unsigned acc_index,
/*
* Update registration. If renew is false, then unregistration will be performed.
*/
-PJ_DECL(void) pjsua_acc_set_registration(unsigned acc_index, pj_bool_t renew)
+PJ_DECL(pj_status_t) pjsua_acc_set_registration(unsigned acc_index, pj_bool_t renew)
{
pj_status_t status = 0;
pjsip_tx_data *tdata = 0;
@@ -143,11 +143,11 @@ PJ_DECL(void) pjsua_acc_set_registration(unsigned acc_index, pj_bool_t renew)
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Unable to create registration",
status);
- return;
+ return PJ_EINVALIDOP;
}
}
if (!pjsua.acc[acc_index].regc)
- return;
+ return PJ_EINVALIDOP;
status = pjsip_regc_register(pjsua.acc[acc_index].regc, 1,
&tdata);
@@ -155,7 +155,7 @@ PJ_DECL(void) pjsua_acc_set_registration(unsigned acc_index, pj_bool_t renew)
} else {
if (pjsua.acc[acc_index].regc == NULL) {
PJ_LOG(3,(THIS_FILE, "Currently not registered"));
- return;
+ return PJ_EINVALIDOP;
}
status = pjsip_regc_unregister(pjsua.acc[acc_index].regc, &tdata);
}
@@ -170,6 +170,8 @@ PJ_DECL(void) pjsua_acc_set_registration(unsigned acc_index, pj_bool_t renew)
PJ_LOG(3,(THIS_FILE, "%s sent",
(renew? "Registration" : "Unregistration")));
}
+
+ return status;
}
/*
diff --git a/pjsip/src/pjsua-lib/pjsua_settings.c b/pjsip/src/pjsua-lib/pjsua_settings.c
index b0cd8558..be615359 100644
--- a/pjsip/src/pjsua-lib/pjsua_settings.c
+++ b/pjsip/src/pjsua-lib/pjsua_settings.c
@@ -685,9 +685,13 @@ static const char *good_number(char *buf, pj_int32_t val)
return buf;
}
-static void dump_media_session(pjmedia_session *session)
+static void dump_media_session(const char *indent,
+ char *buf, unsigned maxlen,
+ pjmedia_session *session)
{
unsigned i;
+ char *p = buf, *end = buf+maxlen;
+ int len;
pjmedia_session_info info;
pjmedia_session_get_info(session, &info);
@@ -715,15 +719,22 @@ static void dump_media_session(pjmedia_session *session)
dir = "inactive";
- PJ_LOG(3,(THIS_FILE,
- "%s#%d %.*s @%dKHz, %s, peer=%s:%d",
- " ",
- i,
+ len = pj_ansi_snprintf(buf, end-p,
+ "%s #%d %.*s @%dKHz, %s, peer=%s:%d",
+ indent, i,
info.stream_info[i].fmt.encoding_name.slen,
info.stream_info[i].fmt.encoding_name.ptr,
info.stream_info[i].fmt.clock_rate / 1000,
dir,
- rem_addr, rem_port));
+ rem_addr, rem_port);
+ if (len < 1 || len > end-p) {
+ *p = '\0';
+ return;
+ }
+
+ p += len;
+ *p++ = '\n';
+ *p = '\0';
if (stat.rx.update_cnt == 0)
strcpy(last_update, "never");
@@ -737,39 +748,48 @@ static void dump_media_session(pjmedia_session *session)
now.msec);
}
- PJ_LOG(3,(THIS_FILE,
- " RX pt=%d, stat last update: %s\n"
- " total %spkt %sB (%sB +IP hdr)%s\n"
- " pkt loss=%d (%3.1f%%), dup=%d (%3.1f%%), reorder=%d (%3.1f%%)%s\n"
- " (msec) min avg max last\n"
- " loss period: %7.3f %7.3f %7.3f %7.3f%s\n"
- " jitter : %7.3f %7.3f %7.3f %7.3f%s",
- info.stream_info[i].fmt.pt,
+ len = pj_ansi_snprintf(p, end-p,
+ "%s RX pt=%d, stat last update: %s\n"
+ "%s total %spkt %sB (%sB +IP hdr)\n"
+ "%s pkt loss=%d (%3.1f%%), dup=%d (%3.1f%%), reorder=%d (%3.1f%%)\n"
+ "%s (msec) min avg max last\n"
+ "%s loss period: %7.3f %7.3f %7.3f %7.3f\n"
+ "%s jitter : %7.3f %7.3f %7.3f %7.3f%s",
+ indent, info.stream_info[i].fmt.pt,
last_update,
+ indent,
good_number(packets, stat.rx.pkt),
good_number(bytes, stat.rx.bytes),
good_number(ipbytes, stat.rx.bytes + stat.rx.pkt * 32),
- "",
+ indent,
stat.rx.loss,
stat.rx.loss * 100.0 / stat.rx.pkt,
stat.rx.dup,
stat.rx.dup * 100.0 / stat.rx.pkt,
stat.rx.reorder,
stat.rx.reorder * 100.0 / stat.rx.pkt,
- "",
+ indent, indent,
stat.rx.loss_period.min / 1000.0,
stat.rx.loss_period.avg / 1000.0,
stat.rx.loss_period.max / 1000.0,
stat.rx.loss_period.last / 1000.0,
- "",
+ indent,
stat.rx.jitter.min / 1000.0,
stat.rx.jitter.avg / 1000.0,
stat.rx.jitter.max / 1000.0,
stat.rx.jitter.last / 1000.0,
""
- ));
+ );
+ if (len < 1 || len > end-p) {
+ *p = '\0';
+ return;
+ }
+ p += len;
+ *p++ = '\n';
+ *p = '\0';
+
if (stat.tx.update_cnt == 0)
strcpy(last_update, "never");
else {
@@ -782,60 +802,152 @@ static void dump_media_session(pjmedia_session *session)
now.msec);
}
- PJ_LOG(3,(THIS_FILE,
- " TX pt=%d, ptime=%dms, stat last update: %s\n"
- " total %spkt %sB (%sB +IP hdr)%s\n"
- " pkt loss=%d (%3.1f%%), dup=%d (%3.1f%%), reorder=%d (%3.1f%%)%s\n"
- " (msec) min avg max last\n"
- " loss period: %7.3f %7.3f %7.3f %7.3f%s\n"
- " jitter : %7.3f %7.3f %7.3f %7.3f%s",
+ len = pj_ansi_snprintf(p, end-p,
+ "%s TX pt=%d, ptime=%dms, stat last update: %s\n"
+ "%s total %spkt %sB (%sB +IP hdr)\n"
+ "%s pkt loss=%d (%3.1f%%), dup=%d (%3.1f%%), reorder=%d (%3.1f%%)\n"
+ "%s (msec) min avg max last\n"
+ "%s loss period: %7.3f %7.3f %7.3f %7.3f\n"
+ "%s jitter : %7.3f %7.3f %7.3f %7.3f%s",
+ indent,
info.stream_info[i].tx_pt,
info.stream_info[i].param->info.frm_ptime *
info.stream_info[i].param->setting.frm_per_pkt,
last_update,
+
+ indent,
good_number(packets, stat.tx.pkt),
good_number(bytes, stat.tx.bytes),
good_number(ipbytes, stat.tx.bytes + stat.tx.pkt * 32),
- "",
+
+ indent,
stat.tx.loss,
stat.tx.loss * 100.0 / stat.tx.pkt,
stat.tx.dup,
stat.tx.dup * 100.0 / stat.tx.pkt,
stat.tx.reorder,
stat.tx.reorder * 100.0 / stat.tx.pkt,
- "",
+
+ indent, indent,
stat.tx.loss_period.min / 1000.0,
stat.tx.loss_period.avg / 1000.0,
stat.tx.loss_period.max / 1000.0,
stat.tx.loss_period.last / 1000.0,
- "",
+ indent,
stat.tx.jitter.min / 1000.0,
stat.tx.jitter.avg / 1000.0,
stat.tx.jitter.max / 1000.0,
stat.tx.jitter.last / 1000.0,
""
- ));
+ );
+
+ if (len < 1 || len > end-p) {
+ *p = '\0';
+ return;
+ }
+ p += len;
+ *p++ = '\n';
+ *p = '\0';
- PJ_LOG(3,(THIS_FILE,
- " RTT msec : %7.3f %7.3f %7.3f %7.3f%s",
+ len = pj_ansi_snprintf(p, end-p,
+ "%s RTT msec : %7.3f %7.3f %7.3f %7.3f",
+ indent,
stat.rtt.min / 1000.0,
stat.rtt.avg / 1000.0,
stat.rtt.max / 1000.0,
- stat.rtt.last / 1000.0,
- ""
- ));
+ stat.rtt.last / 1000.0
+ );
+ if (len < 1 || len > end-p) {
+ *p = '\0';
+ return;
+ }
+ p += len;
+ *p++ = '\n';
+ *p = '\0';
}
}
+PJ_DEF(void) pjsua_dump_call(int call_index, int with_media,
+ char *buffer, unsigned maxlen,
+ const char *indent)
+{
+ pjsua_call *call = &pjsua.calls[call_index];
+ pj_time_val duration, res_delay, con_delay;
+ char tmp[128];
+ char *p, *end;
+ int len;
+
+ *buffer = '\0';
+ p = buffer;
+ end = buffer + maxlen;
+ len = 0;
+
+ PJ_ASSERT_ON_FAIL(call_index >= 0 &&
+ call_index < PJ_ARRAY_SIZE(pjsua.calls), return);
+
+ if (call->inv == NULL)
+ return;
+
+ print_call(indent, call_index, tmp, sizeof(tmp));
+
+ len = pj_ansi_strlen(tmp);
+ pj_ansi_strcpy(buffer, tmp);
+
+ p += len;
+ *p++ = '\r';
+ *p++ = '\n';
+
+ /* Calculate call duration */
+ if (call->inv->state >= PJSIP_INV_STATE_CONFIRMED) {
+ pj_gettimeofday(&duration);
+ PJ_TIME_VAL_SUB(duration, call->conn_time);
+ con_delay = call->conn_time;
+ PJ_TIME_VAL_SUB(con_delay, call->start_time);
+ } else {
+ duration.sec = duration.msec = 0;
+ con_delay.sec = con_delay.msec = 0;
+ }
+
+ /* Calculate first response delay */
+ if (call->inv->state >= PJSIP_INV_STATE_EARLY) {
+ res_delay = call->res_time;
+ PJ_TIME_VAL_SUB(res_delay, call->start_time);
+ } else {
+ res_delay.sec = res_delay.msec = 0;
+ }
+
+ /* Print duration */
+ len = pj_ansi_snprintf(p, end-p,
+ "%s Call time: %02dh:%02dm:%02ds, "
+ "1st res in %d ms, conn in %dms",
+ indent,
+ (duration.sec / 3600),
+ ((duration.sec % 3600)/60),
+ (duration.sec % 60),
+ PJ_TIME_VAL_MSEC(res_delay),
+ PJ_TIME_VAL_MSEC(con_delay));
+
+ if (len > 0 && len < end-p) {
+ p += len;
+ *p++ = '\n';
+ *p = '\0';
+ }
+
+ /* Dump session statistics */
+ if (with_media && call->session)
+ dump_media_session(indent, p, end-p, call->session);
+
+}
+
/*
* Dump application states.
*/
PJ_DEF(void) pjsua_dump(pj_bool_t detail)
{
- char buf[128];
unsigned old_decor;
+ char buf[1024];
PJ_LOG(3,(THIS_FILE, "Start dumping application states:"));
@@ -862,48 +974,10 @@ PJ_DEF(void) pjsua_dump(pj_bool_t detail)
unsigned i;
for (i=0; i<pjsua.config.max_calls; ++i) {
-
- pjsua_call *call = &pjsua.calls[i];
- pj_time_val duration, res_delay, con_delay;
-
- if (call->inv == NULL)
- continue;
-
- print_call(" ", i, buf, sizeof(buf));
- PJ_LOG(3,(THIS_FILE, "%s", buf));
-
- /* Calculate call duration */
- if (call->inv->state >= PJSIP_INV_STATE_CONFIRMED) {
- pj_gettimeofday(&duration);
- PJ_TIME_VAL_SUB(duration, call->conn_time);
- con_delay = call->conn_time;
- PJ_TIME_VAL_SUB(con_delay, call->start_time);
- } else {
- duration.sec = duration.msec = 0;
- con_delay.sec = con_delay.msec = 0;
- }
-
- /* Calculate first response delay */
- if (call->inv->state >= PJSIP_INV_STATE_EARLY) {
- res_delay = call->res_time;
- PJ_TIME_VAL_SUB(res_delay, call->start_time);
- } else {
- res_delay.sec = res_delay.msec = 0;
+ if (pjsua.calls[i].inv) {
+ pjsua_dump_call(i, detail, buf, sizeof(buf), " ");
+ PJ_LOG(3,(THIS_FILE, "%s", buf));
}
-
- /* Print duration */
- PJ_LOG(3,(THIS_FILE,
- " Call time: %02dh:%02dm:%02ds, "
- "1st res in %d ms, conn in %dms",
- (duration.sec / 3600),
- ((duration.sec % 3600)/60),
- (duration.sec % 60),
- PJ_TIME_VAL_MSEC(res_delay),
- PJ_TIME_VAL_MSEC(con_delay)));
-
- /* Dump session statistics */
- if (call->session)
- dump_media_session(call->session);
}
}
@@ -924,7 +998,7 @@ PJ_DECL(pj_status_t) pjsua_load_settings(const char *filename,
int argc = 3;
char *argv[4] = { "pjsua", "--config-file", NULL, NULL};
- argv[3] = (char*)filename;
+ argv[2] = (char*)filename;
return pjsua_parse_args(argc, argv, cfg);
}
@@ -1103,12 +1177,16 @@ PJ_DEF(int) pjsua_dump_settings(const pjsua_config *config,
/* Encoding quality and complexity */
- pj_ansi_sprintf(line, "--quality %d\n",
- config->quality);
- pj_strcat2(&cfg, line);
- pj_ansi_sprintf(line, "--complexity %d\n",
- config->complexity);
- pj_strcat2(&cfg, line);
+ if (config->quality > 0) {
+ pj_ansi_sprintf(line, "--quality %d\n",
+ config->quality);
+ pj_strcat2(&cfg, line);
+ }
+ if (config->complexity > 0) {
+ pj_ansi_sprintf(line, "--complexity %d\n",
+ config->complexity);
+ pj_strcat2(&cfg, line);
+ }
/* ptime */
if (config->ptime) {