diff options
Diffstat (limited to 'pjsip')
-rw-r--r-- | pjsip/include/pjsua-lib/pjsua.h | 31 | ||||
-rw-r--r-- | pjsip/include/pjsua-lib/pjsua_console_app.h | 3 | ||||
-rw-r--r-- | pjsip/src/pjsua-lib/pjsua_console_app.c | 57 | ||||
-rw-r--r-- | pjsip/src/pjsua-lib/pjsua_core.c | 121 | ||||
-rw-r--r-- | pjsip/src/pjsua-lib/pjsua_imp.h | 3 | ||||
-rw-r--r-- | pjsip/src/pjsua-lib/pjsua_pres.c | 13 | ||||
-rw-r--r-- | pjsip/src/pjsua-lib/pjsua_reg.c | 10 | ||||
-rw-r--r-- | pjsip/src/pjsua-lib/pjsua_settings.c | 244 |
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) { |