diff options
Diffstat (limited to 'pjsip/src/pjsua/pjsua_opt.c')
-rw-r--r-- | pjsip/src/pjsua/pjsua_opt.c | 316 |
1 files changed, 240 insertions, 76 deletions
diff --git a/pjsip/src/pjsua/pjsua_opt.c b/pjsip/src/pjsua/pjsua_opt.c index 52819265..5ec37980 100644 --- a/pjsip/src/pjsua/pjsua_opt.c +++ b/pjsip/src/pjsua/pjsua_opt.c @@ -43,8 +43,6 @@ static void usage(void) puts("Usage:"); puts(" pjsua [options]"); puts(""); - puts(" [sip-url] Default URL to invite."); - puts(""); puts("General options:"); puts(" --help Display this help screen"); puts(" --version Display version info"); @@ -55,36 +53,43 @@ static void usage(void) puts(" --log-level=N Set log max level to N (0(none) to 6(trace))"); puts(" --app-log-level=N Set log max level for stdout display to N"); puts(""); - puts("Authentication options:"); - puts(" --realm=string Set realm"); - puts(" --username=string Set authentication username"); - puts(" --password=string Set authentication password"); - puts(""); - puts("SIP options:"); + puts("SIP Account options:"); puts(" --id=url Set the URL of local ID (used in From header)"); puts(" --contact=url Override the Contact information"); puts(" --proxy=url Set the URL of proxy server"); - //puts(" --outbound=url Set the URL of outbound proxy server"); puts(""); - puts("Registration Options:"); + puts("SIP Account Registration Options:"); puts(" --registrar=url Set the URL of registrar server"); puts(" --reg-timeout=secs Set registration interval to secs (default 3600)"); puts(""); + puts("SIP Account Control:"); + puts(" --next-account Add more account"); + puts(""); + puts("Authentication options:"); + puts(" --realm=string Set realm"); + puts(" --username=string Set authentication username"); + puts(" --password=string Set authentication password"); + puts(" --next-cred Add more credential"); + puts(""); puts("Transport Options:"); - puts(" --local-port=port Set TCP/UDP port"); + puts(" --local-port=port Set TCP/UDP port"); + puts(" --outbound=url Set the URL of outbound proxy server"); puts(" --use-stun1=host[:port]"); - puts(" --use-stun2=host[:port] Use STUN and set host name and port of STUN servers"); + puts(" --use-stun2=host[:port] Resolve local IP with the specified STUN servers"); puts(""); puts("Media Options:"); puts(" --null-audio Use NULL audio device"); - //puts(" --wav-file=file Play WAV file in conference bridge"); + puts(" --play-file=file Play WAV file in conference bridge"); + puts(" --auto-play Automatically play the file (to incoming calls only)"); + puts(" --auto-loop Automatically loop incoming RTP to outgoing RTP"); + puts(" --auto-conf Automatically put incoming calls to conference"); puts(""); puts("Buddy List (can be more than one):"); puts(" --add-buddy url Add the specified URL to the buddy list."); puts(""); puts("User Agent options:"); puts(" --auto-answer=code Automatically answer incoming calls with code (e.g. 200)"); - puts(" --auto-play=file Automatically play WAVE file to incoming calls"); + puts(" --max-calls=N Maximum number of concurrent calls (default:4, max:255)"); puts(""); fflush(stdout); } @@ -199,7 +204,11 @@ pj_status_t pjsua_parse_args(int argc, char *argv[]) OPT_REALM, OPT_USERNAME, OPT_PASSWORD, OPT_USE_STUN1, OPT_USE_STUN2, OPT_ADD_BUDDY, OPT_OFFER_X_MS_MSG, OPT_NO_PRESENCE, - OPT_AUTO_ANSWER, OPT_AUTO_HANGUP, OPT_AUTO_PLAY}; + OPT_AUTO_ANSWER, OPT_AUTO_HANGUP, OPT_AUTO_PLAY, OPT_AUTO_LOOP, + OPT_AUTO_CONF, + OPT_PLAY_FILE, + OPT_NEXT_ACCOUNT, OPT_NEXT_CRED, OPT_MAX_CALLS, + }; struct option long_options[] = { { "config-file",1, 0, OPT_CONFIG_FILE}, { "log-file", 1, 0, OPT_LOG_FILE}, @@ -225,10 +234,18 @@ pj_status_t pjsua_parse_args(int argc, char *argv[]) { "no-presence", 0, 0, OPT_NO_PRESENCE}, { "auto-answer",1, 0, OPT_AUTO_ANSWER}, { "auto-hangup",1, 0, OPT_AUTO_HANGUP}, - { "auto-play", 1, 0, OPT_AUTO_PLAY}, + { "auto-play", 0, 0, OPT_AUTO_PLAY}, + { "auto-loop", 0, 0, OPT_AUTO_LOOP}, + { "auto-conf", 0, 0, OPT_AUTO_CONF}, + { "play-file", 1, 0, OPT_PLAY_FILE}, + { "next-account",0,0, OPT_NEXT_ACCOUNT}, + { "next-cred", 0, 0, OPT_NEXT_CRED}, + { "max-calls", 1, 0, OPT_MAX_CALLS}, { NULL, 0, 0, 0} }; pj_status_t status; + pjsua_acc *cur_acc; + pjsip_cred_info *cur_cred; char *config_file = NULL; /* Run getopt once to see if user specifies config file to read. */ @@ -249,6 +266,10 @@ pj_status_t pjsua_parse_args(int argc, char *argv[]) } + cur_acc = &pjsua.acc[0]; + cur_cred = &pjsua.cred_info[0]; + + /* Reinitialize and re-run getopt again, possibly with new arguments * read from config file. */ @@ -307,7 +328,7 @@ pj_status_t pjsua_parse_args(int argc, char *argv[]) printf("Error: invalid SIP URL '%s' in proxy argument\n", optarg); return PJ_EINVAL; } - pjsua.proxy = pj_str(optarg); + cur_acc->proxy = pj_str(optarg); break; case OPT_OUTBOUND_PROXY: /* outbound proxy */ @@ -323,12 +344,12 @@ pj_status_t pjsua_parse_args(int argc, char *argv[]) printf("Error: invalid SIP URL '%s' in registrar argument\n", optarg); return PJ_EINVAL; } - pjsua.registrar_uri = pj_str(optarg); + cur_acc->reg_uri = pj_str(optarg); break; case OPT_REG_TIMEOUT: /* reg-timeout */ - pjsua.reg_timeout = pj_strtoul(pj_cstr(&tmp,optarg)); - if (pjsua.reg_timeout < 1 || pjsua.reg_timeout > 3600) { + cur_acc->reg_timeout = pj_strtoul(pj_cstr(&tmp,optarg)); + if (cur_acc->reg_timeout < 1 || cur_acc->reg_timeout > 3600) { printf("Error: invalid value for --reg-timeout (expecting 1-3600)\n"); return PJ_EINVAL; } @@ -339,7 +360,7 @@ pj_status_t pjsua_parse_args(int argc, char *argv[]) printf("Error: invalid SIP URL '%s' in local id argument\n", optarg); return PJ_EINVAL; } - pjsua.local_uri = pj_str(optarg); + cur_acc->local_uri = pj_str(optarg); break; case OPT_CONTACT: /* contact */ @@ -347,23 +368,33 @@ pj_status_t pjsua_parse_args(int argc, char *argv[]) printf("Error: invalid SIP URL '%s' in contact argument\n", optarg); return PJ_EINVAL; } - pjsua.contact_uri = pj_str(optarg); + cur_acc->contact_uri = pj_str(optarg); + break; + + case OPT_NEXT_ACCOUNT: /* Add more account. */ + pjsua.acc_cnt++; + cur_acc = &pjsua.acc[pjsua.acc_cnt - 1]; break; case OPT_USERNAME: /* Default authentication user */ - if (!pjsua.cred_count) pjsua.cred_count = 1; - pjsua.cred_info[0].username = pj_str(optarg); + if (pjsua.cred_count==0) pjsua.cred_count=1; + cur_cred->username = pj_str(optarg); break; case OPT_REALM: /* Default authentication realm. */ - if (!pjsua.cred_count) pjsua.cred_count = 1; - pjsua.cred_info[0].realm = pj_str(optarg); + if (pjsua.cred_count==0) pjsua.cred_count=1; + cur_cred->realm = pj_str(optarg); break; case OPT_PASSWORD: /* authentication password */ - if (!pjsua.cred_count) pjsua.cred_count = 1; - pjsua.cred_info[0].data_type = 0; - pjsua.cred_info[0].data = pj_str(optarg); + if (pjsua.cred_count==0) pjsua.cred_count=1; + cur_cred->data_type = 0; + cur_cred->data = pj_str(optarg); + break; + + case OPT_NEXT_CRED: /* Next credential */ + pjsua.cred_count++; + cur_cred = &pjsua.cred_info[pjsua.cred_count - 1]; break; case OPT_USE_STUN1: /* STUN server 1 */ @@ -411,6 +442,18 @@ pj_status_t pjsua_parse_args(int argc, char *argv[]) break; case OPT_AUTO_PLAY: + pjsua.auto_play = 1; + break; + + case OPT_AUTO_LOOP: + pjsua.auto_loop = 1; + break; + + case OPT_AUTO_CONF: + pjsua.auto_conf = 1; + break; + + case OPT_PLAY_FILE: pjsua.wav_file = optarg; break; @@ -421,6 +464,14 @@ pj_status_t pjsua_parse_args(int argc, char *argv[]) return -1; } break; + + case OPT_MAX_CALLS: + pjsua.max_calls = atoi(optarg); + if (pjsua.max_calls < 1 || pjsua.max_calls > 255) { + puts("Too many calls for max-calls (1-255)"); + return -1; + } + break; } } @@ -429,21 +480,17 @@ pj_status_t pjsua_parse_args(int argc, char *argv[]) return PJ_EINVAL; } - if (pjsua.reg_timeout == 0) - pjsua.reg_timeout = 3600; - - return PJ_SUCCESS; } -static void print_invite_session(const char *title, - struct pjsua_inv_data *inv_data, - char *buf, pj_size_t size) +static void print_call(const char *title, + int call_index, + char *buf, pj_size_t size) { int len; - pjsip_inv_session *inv = inv_data->inv; + pjsip_inv_session *inv = pjsua.calls[call_index].inv; pjsip_dialog *dlg = inv->dlg; char userinfo[128]; @@ -515,7 +562,6 @@ static void dump_media_session(pjmedia_session *session) */ void pjsua_dump(void) { - struct pjsua_inv_data *inv_data; char buf[128]; unsigned old_decor; @@ -533,23 +579,23 @@ void pjsua_dump(void) /* Dump all invite sessions: */ PJ_LOG(3,(THIS_FILE, "Dumping invite sessions:")); - if (pj_list_empty(&pjsua.inv_list)) { + if (pjsua.call_cnt == 0) { PJ_LOG(3,(THIS_FILE, " - no sessions -")); } else { + int i; - inv_data = pjsua.inv_list.next; + for (i=0; i<pjsua.max_calls; ++i) { - while (inv_data != &pjsua.inv_list) { + if (pjsua.calls[i].inv == NULL) + continue; - print_invite_session(" ", inv_data, buf, sizeof(buf)); + print_call(" ", i, buf, sizeof(buf)); PJ_LOG(3,(THIS_FILE, "%s", buf)); - if (inv_data->session) - dump_media_session(inv_data->session); - - inv_data = inv_data->next; + if (pjsua.calls[i].session) + dump_media_session(pjsua.calls[i].session); } } @@ -575,40 +621,96 @@ pj_status_t pjsua_load_settings(const char *filename) /* - * Save settings. + * Save account settings */ -pj_status_t pjsua_save_settings(const char *filename) +static void save_account_settings(int acc_index, pj_str_t *result) { - unsigned i; - pj_str_t cfg; char line[128]; - pj_pool_t *pool; - FILE *fhnd; + pjsua_acc *acc = &pjsua.acc[acc_index]; - /* Create pool for temporary buffer. */ - pool = pj_pool_create(&pjsua.cp.factory, "settings", 4000, 0, NULL); - if (!pool) - return PJ_ENOMEM; + + pj_ansi_sprintf(line, "#\n# Account %d:\n#\n", acc_index); + pj_strcat2(result, line); - cfg.ptr = pj_pool_alloc(pool, 3800); - if (!cfg.ptr) { - pj_pool_release(pool); - return PJ_EBUG; + /* Identity */ + if (acc->local_uri.slen) { + pj_ansi_sprintf(line, "--id %.*s\n", + (int)acc->local_uri.slen, + acc->local_uri.ptr); + pj_strcat2(result, line); + } + + /* Registrar server */ + if (acc->reg_uri.slen) { + pj_ansi_sprintf(line, "--registrar %.*s\n", + (int)acc->reg_uri.slen, + acc->reg_uri.ptr); + pj_strcat2(result, line); + + pj_ansi_sprintf(line, "--reg-timeout %u\n", + acc->reg_timeout); + pj_strcat2(result, line); } + + + /* Proxy */ + if (acc->proxy.slen) { + pj_ansi_sprintf(line, "--proxy %.*s\n", + (int)acc->proxy.slen, + acc->proxy.ptr); + pj_strcat2(result, line); + } +} + + + +/* + * Dump settings. + */ +int pjsua_dump_settings(char *buf, pj_size_t max) +{ + int acc_index; + int i; + pj_str_t cfg; + char line[128]; + + cfg.ptr = buf; cfg.slen = 0; - /* Identity */ - if (pjsua.local_uri.slen) { - pj_ansi_sprintf(line, "--id %.*s\n", - (int)pjsua.local_uri.slen, - pjsua.local_uri.ptr); + /* Logging. */ + pj_strcat2(&cfg, "#\n# Logging options:\n#\n"); + pj_ansi_sprintf(line, "--log-level %d\n", + pjsua.log_level); + pj_strcat2(&cfg, line); + + pj_ansi_sprintf(line, "--app-log-level %d\n", + pjsua.app_log_level); + pj_strcat2(&cfg, line); + + if (pjsua.log_filename) { + pj_ansi_sprintf(line, "--log-file %s\n", + pjsua.log_filename); pj_strcat2(&cfg, line); } + + /* Save account settings. */ + for (acc_index=0; acc_index < pjsua.acc_cnt; ++acc_index) { + + save_account_settings(acc_index, &cfg); + + if (acc_index < pjsua.acc_cnt-1) + pj_strcat2(&cfg, "--next-account\n"); + } + /* Credentials. */ for (i=0; i<pjsua.cred_count; ++i) { + + pj_ansi_sprintf(line, "#\n# Credential %d:\n#\n", i); + pj_strcat2(&cfg, line); + if (pjsua.cred_info[i].realm.slen) { pj_ansi_sprintf(line, "--realm %.*s\n", (int)pjsua.cred_info[i].realm.slen, @@ -625,17 +727,14 @@ pj_status_t pjsua_save_settings(const char *filename) (int)pjsua.cred_info[i].data.slen, pjsua.cred_info[i].data.ptr); pj_strcat2(&cfg, line); - } - /* Registrar server */ - if (pjsua.registrar_uri.slen) { - pj_ansi_sprintf(line, "--registrar %.*s\n", - (int)pjsua.registrar_uri.slen, - pjsua.registrar_uri.ptr); - pj_strcat2(&cfg, line); + if (i < pjsua.cred_count-1) + pj_strcat2(&cfg, "--next-cred\n"); } + pj_strcat2(&cfg, "#\n# Network settings:\n#\n"); + /* Outbound proxy */ if (pjsua.outbound_proxy.slen) { pj_ansi_sprintf(line, "--outbound %.*s\n", @@ -644,10 +743,6 @@ pj_status_t pjsua_save_settings(const char *filename) pj_strcat2(&cfg, line); } - /* Media */ - if (pjsua.null_audio) - pj_strcat2(&cfg, "--null-audio\n"); - /* Transport. */ pj_ansi_sprintf(line, "--local-port %d\n", pjsua.sip_port); @@ -672,6 +767,42 @@ pj_status_t pjsua_save_settings(const char *filename) } + pj_strcat2(&cfg, "#\n# Media settings:\n#\n"); + + + /* Media */ + if (pjsua.null_audio) + pj_strcat2(&cfg, "--null-audio\n"); + if (pjsua.auto_play) + pj_strcat2(&cfg, "--auto-play\n"); + if (pjsua.auto_loop) + pj_strcat2(&cfg, "--auto-loop\n"); + if (pjsua.auto_conf) + pj_strcat2(&cfg, "--auto-conf\n"); + if (pjsua.wav_file) { + pj_ansi_sprintf(line, "--play-file %s\n", + pjsua.wav_file); + pj_strcat2(&cfg, line); + } + + + pj_strcat2(&cfg, "#\n# User agent:\n#\n"); + + /* Auto-answer. */ + if (pjsua.auto_answer != 0) { + pj_ansi_sprintf(line, "--auto-answer %d\n", + pjsua.auto_answer); + pj_strcat2(&cfg, line); + } + + /* Max calls. */ + pj_ansi_sprintf(line, "--max-calls %d\n", + pjsua.max_calls); + pj_strcat2(&cfg, line); + + + pj_strcat2(&cfg, "#\n# Buddies:\n#\n"); + /* Add buddies. */ for (i=0; i<pjsua.buddy_cnt; ++i) { pj_ansi_sprintf(line, "--add-buddy %.*s\n", @@ -681,6 +812,39 @@ pj_status_t pjsua_save_settings(const char *filename) } + *(cfg.ptr + cfg.slen) = '\0'; + return cfg.slen; +} + +/* + * Save settings. + */ +pj_status_t pjsua_save_settings(const char *filename) +{ + pj_str_t cfg; + pj_pool_t *pool; + FILE *fhnd; + + /* Create pool for temporary buffer. */ + pool = pj_pool_create(&pjsua.cp.factory, "settings", 4000, 0, NULL); + if (!pool) + return PJ_ENOMEM; + + + cfg.ptr = pj_pool_alloc(pool, 3800); + if (!cfg.ptr) { + pj_pool_release(pool); + return PJ_EBUG; + } + + + cfg.slen = pjsua_dump_settings(cfg.ptr, 3800); + if (cfg.slen < 1) { + pj_pool_release(pool); + return PJ_ENOMEM; + } + + /* Write to file. */ fhnd = fopen(filename, "wt"); if (!fhnd) { |