From 185de1159231659d85b2ed4f18298176da51f666 Mon Sep 17 00:00:00 2001 From: Benny Prijono Date: Sun, 5 Mar 2006 11:54:02 +0000 Subject: Added complexity and quality argument, and terminate dialog properly on failures git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@284 74dad513-b988-da41-8d7b-12977e46ad98 --- pjsip/include/pjsua-lib/pjsua.h | 5 +- pjsip/src/pjsua-lib/pjsua_call.c | 64 ++++++++++++++--- pjsip/src/pjsua-lib/pjsua_core.c | 8 ++- pjsip/src/pjsua-lib/pjsua_pres.c | 18 ++--- pjsip/src/pjsua-lib/pjsua_settings.c | 133 ++++++++++++++++++++--------------- 5 files changed, 150 insertions(+), 78 deletions(-) (limited to 'pjsip') diff --git a/pjsip/include/pjsua-lib/pjsua.h b/pjsip/include/pjsua-lib/pjsua.h index fe778be6..978af96f 100644 --- a/pjsip/include/pjsua-lib/pjsua.h +++ b/pjsip/include/pjsua-lib/pjsua.h @@ -185,6 +185,9 @@ struct pjsua pj_bool_t auto_play; /**< Auto play file for calls? */ pj_bool_t auto_loop; /**< Auto loop RTP stream? */ pj_bool_t auto_conf; /**< Auto put to conference? */ + int complexity; /**< Codec complexity. */ + int quality; /**< Codec quality. */ + /* Codec arguments: */ int codec_cnt; /**< Number of --add-codec args. */ @@ -337,7 +340,7 @@ void pjsua_call_answer(int call_index, int code); /** * Hangup call. */ -void pjsua_call_hangup(int call_index, int code); +void pjsua_call_hangup(int call_index); /** diff --git a/pjsip/src/pjsua-lib/pjsua_call.c b/pjsip/src/pjsua-lib/pjsua_call.c index 612ccd0a..1fc80604 100644 --- a/pjsip/src/pjsua-lib/pjsua_call.c +++ b/pjsip/src/pjsua-lib/pjsua_call.c @@ -37,9 +37,9 @@ pj_status_t pjsua_make_call(int acc_index, int *p_call_index) { pj_str_t dest_uri; - pjsip_dialog *dlg; + pjsip_dialog *dlg = NULL; pjmedia_sdp_session *offer; - pjsip_inv_session *inv; + pjsip_inv_session *inv = NULL; int call_index = -1; pjsip_tx_data *tdata; pj_status_t status; @@ -141,7 +141,12 @@ pj_status_t pjsua_make_call(int acc_index, on_error: - PJ_TODO(DESTROY_DIALOG_ON_FAIL); + if (inv != NULL) { + pjsip_inv_terminate(inv, PJSIP_SC_OK, PJ_FALSE); + } else { + pjsip_dlg_terminate(dlg); + } + if (call_index != -1) { pjsua.calls[call_index].inv = NULL; } @@ -159,7 +164,7 @@ pj_bool_t pjsua_call_on_incoming(pjsip_rx_data *rdata) pjsip_msg *msg = rdata->msg_info.msg; pjsip_tx_data *response = NULL; unsigned options = 0; - pjsip_inv_session *inv; + pjsip_inv_session *inv = NULL; int acc_index; int call_index = -1; pjmedia_sdp_session *answer; @@ -260,8 +265,7 @@ pj_bool_t pjsua_call_on_incoming(pjsip_rx_data *rdata) if (status != PJ_SUCCESS) { pjsip_dlg_respond(dlg, rdata, 500, NULL, NULL, NULL); - - // TODO: Need to delete dialog + pjsip_dlg_terminate(dlg); return PJ_TRUE; } @@ -286,8 +290,7 @@ pj_bool_t pjsua_call_on_incoming(pjsip_rx_data *rdata) pjsua_perror(THIS_FILE, "Unable to create 100 response", status); pjsip_dlg_respond(dlg, rdata, 500, NULL, NULL, NULL); - - // TODO: Need to delete dialog + pjsip_inv_terminate(inv, 500, PJ_FALSE); } else { status = pjsip_inv_send_msg(inv, response, NULL); @@ -722,6 +725,21 @@ static void pjsua_call_on_rx_offer(pjsip_inv_session *inv, } +/* Disconnect call */ +static void call_disconnect(pjsip_inv_session *inv, + int st_code) +{ + pjsip_tx_data *tdata; + pj_status_t status; + + status = pjsip_inv_end_session(inv, st_code, NULL, &tdata); + if (status == PJ_SUCCESS) + status = pjsip_inv_send_msg(inv, tdata, NULL); + + if (status != PJ_SUCCESS) { + pjsua_perror(THIS_FILE, "Unable to disconnect call", status); + } +} /* * Callback to be called when SDP offer/answer negotiation has just completed @@ -743,6 +761,11 @@ static void pjsua_call_on_media_update(pjsip_inv_session *inv, if (status != PJ_SUCCESS) { pjsua_perror(THIS_FILE, "SDP negotiation has failed", status); + + /* Disconnect call if this is not a re-INVITE */ + if (inv->state != PJSIP_INV_STATE_CONFIRMED) { + call_disconnect(inv, PJSIP_SC_UNSUPPORTED_MEDIA_TYPE); + } return; } @@ -762,6 +785,7 @@ static void pjsua_call_on_media_update(pjsip_inv_session *inv, pjsua_perror(THIS_FILE, "Unable to retrieve currently active local SDP", status); + call_disconnect(inv, PJSIP_SC_UNSUPPORTED_MEDIA_TYPE); return; } @@ -771,6 +795,7 @@ static void pjsua_call_on_media_update(pjsip_inv_session *inv, pjsua_perror(THIS_FILE, "Unable to retrieve currently active remote SDP", status); + call_disconnect(inv, PJSIP_SC_UNSUPPORTED_MEDIA_TYPE); return; } @@ -788,6 +813,7 @@ static void pjsua_call_on_media_update(pjsip_inv_session *inv, if (status != PJ_SUCCESS) { pjsua_perror(THIS_FILE, "Unable to create media session", status); + call_disconnect(inv, PJSIP_SC_UNSUPPORTED_MEDIA_TYPE); return; } @@ -817,6 +843,7 @@ static void pjsua_call_on_media_update(pjsip_inv_session *inv, status); pjmedia_session_destroy(call->session); call->session = NULL; + call_disconnect(inv, PJSIP_SC_INTERNAL_SERVER_ERROR); return; } @@ -909,9 +936,10 @@ static void pjsua_call_on_media_update(pjsip_inv_session *inv, /* * Hangup call. */ -void pjsua_call_hangup(int call_index, int code) +void pjsua_call_hangup(int call_index) { pjsua_call *call; + int code; pj_status_t status; pjsip_tx_data *tdata; @@ -923,6 +951,13 @@ void pjsua_call_hangup(int call_index, int code) return; } + if (call->inv->state == PJSIP_INV_STATE_CONFIRMED) + code = PJSIP_SC_OK; + else if (call->inv->role == PJSIP_ROLE_UAS) + code = PJSIP_SC_DECLINE; + else + code = PJSIP_SC_REQUEST_TERMINATED; + status = pjsip_inv_end_session(call->inv, code, NULL, &tdata); if (status != PJ_SUCCESS) { pjsua_perror(THIS_FILE, @@ -1189,12 +1224,13 @@ on_return: /* * Terminate all calls. */ -void pjsua_call_hangup_all() +void pjsua_call_hangup_all(void) { int i; for (i=0; iinv, 410, NULL, &tdata)==0) { + if (call->inv->state == PJSIP_INV_STATE_CONFIRMED) { + st_code = 200; + } else { + st_code = PJSIP_SC_GONE; + } + + if (pjsip_inv_end_session(call->inv, st_code, NULL, &tdata)==0) { if (tdata) pjsip_inv_send_msg(call->inv, tdata, NULL); } diff --git a/pjsip/src/pjsua-lib/pjsua_core.c b/pjsip/src/pjsua-lib/pjsua_core.c index 1f975142..2744f4eb 100644 --- a/pjsip/src/pjsua-lib/pjsua_core.c +++ b/pjsip/src/pjsua-lib/pjsua_core.c @@ -72,8 +72,11 @@ void pjsua_default(void) /* Default: do not use STUN: */ pjsua.stun_port1 = pjsua.stun_port2 = 0; - /* Default: sampling rate is 8000 */ + /* Default for media: */ pjsua.clock_rate = 8000; + pjsua.complexity = 4; + pjsua.quality = 4; + /* Init accounts: */ pjsua.acc_cnt = 1; @@ -614,7 +617,8 @@ static pj_status_t init_media(void) if (pjsua.clock_rate >= 32000) option &= ~(PJMEDIA_SPEEX_NO_UWB); - status = pjmedia_codec_speex_init(pjsua.med_endpt, option, -1, -1); + status = pjmedia_codec_speex_init(pjsua.med_endpt, option, + pjsua.quality, pjsua.complexity ); if (status != PJ_SUCCESS) { pjsua_perror(THIS_FILE, "Error initializing Speex codec", status); diff --git a/pjsip/src/pjsua-lib/pjsua_pres.c b/pjsip/src/pjsua-lib/pjsua_pres.c index 174a106d..f0774d5f 100644 --- a/pjsip/src/pjsua-lib/pjsua_pres.c +++ b/pjsip/src/pjsua-lib/pjsua_pres.c @@ -115,7 +115,7 @@ static pj_bool_t pres_on_rx_request(pjsip_rx_data *rdata) /* Create server presence subscription: */ status = pjsip_pres_create_uas( dlg, &pres_cb, rdata, &sub); if (status != PJ_SUCCESS) { - PJ_TODO(DESTROY_DIALOG); + pjsip_dlg_terminate(dlg); pjsua_perror(THIS_FILE, "Unable to create server subscription", status); return PJ_FALSE; @@ -144,6 +144,7 @@ static pj_bool_t pres_on_rx_request(pjsip_rx_data *rdata) pjsua_perror(THIS_FILE, "Unable to accept presence subscription", status); pj_list_erase(uapres); + pjsip_pres_terminate(sub, PJ_FALSE); return PJ_FALSE; } @@ -168,6 +169,7 @@ static pj_bool_t pres_on_rx_request(pjsip_rx_data *rdata) pjsua_perror(THIS_FILE, "Unable to create/send NOTIFY", status); pj_list_erase(uapres); + pjsip_pres_terminate(sub, PJ_FALSE); return PJ_FALSE; } @@ -327,6 +329,7 @@ static void subscribe_buddy_presence(unsigned index) pjsua.buddies[index].sub = NULL; pjsua_perror(THIS_FILE, "Unable to create presence client", status); + pjsip_dlg_terminate(dlg); return; } @@ -335,6 +338,7 @@ static void subscribe_buddy_presence(unsigned index) status = pjsip_pres_initiate(pjsua.buddies[index].sub, -1, &tdata); if (status != PJ_SUCCESS) { + pjsip_pres_terminate(pjsua.buddies[index].sub, PJ_FALSE); pjsua.buddies[index].sub = NULL; pjsua_perror(THIS_FILE, "Unable to create initial SUBSCRIBE", status); @@ -343,13 +347,12 @@ static void subscribe_buddy_presence(unsigned index) status = pjsip_pres_send_request(pjsua.buddies[index].sub, tdata); if (status != PJ_SUCCESS) { + pjsip_pres_terminate(pjsua.buddies[index].sub, PJ_FALSE); pjsua.buddies[index].sub = NULL; pjsua_perror(THIS_FILE, "Unable to send initial SUBSCRIBE", status); return; } - - PJ_TODO(DESTROY_DIALOG_ON_ERROR); } @@ -373,13 +376,10 @@ static void unsubscribe_buddy_presence(unsigned index) if (status == PJ_SUCCESS) status = pjsip_pres_send_request( pjsua.buddies[index].sub, tdata ); - if (status == PJ_SUCCESS) { - - //pjsip_evsub_set_mod_data(pjsua.buddies[index].sub, pjsua.mod.id, - // NULL); - //pjsua.buddies[index].sub = NULL; + if (status != PJ_SUCCESS) { - } else { + pjsip_pres_terminate(pjsua.buddies[index].sub, PJ_FALSE); + pjsua.buddies[index].sub = NULL; pjsua_perror(THIS_FILE, "Unable to unsubscribe presence", status); } diff --git a/pjsip/src/pjsua-lib/pjsua_settings.c b/pjsip/src/pjsua-lib/pjsua_settings.c index 810d645a..18aec9af 100644 --- a/pjsip/src/pjsua-lib/pjsua_settings.c +++ b/pjsip/src/pjsua-lib/pjsua_settings.c @@ -45,61 +45,63 @@ const char *pjsua_inv_state_names[] = /* Show usage */ static void usage(void) { - puts("Usage:"); - puts(" pjsua [options]"); - puts(""); - puts("General options:"); - puts(" --help Display this help screen"); - puts(" --version Display version info"); - puts(""); - puts("Logging options:"); - puts(" --config-file=file Read the config/arguments from file."); - puts(" --log-file=fname Log to filename (default stderr)"); - 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("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(""); - 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(" --outbound=url Set the URL of outbound proxy server"); - puts(" --use-stun1=host[:port]"); - puts(" --use-stun2=host[:port] Resolve local IP with the specified STUN servers"); - puts(""); - puts("Media Options:"); - puts(" --wb Enable wideband codecs (16KHz)"); - puts(" --uwb Enable ultra-wideband codecs (32KHz)"); - puts(" --null-audio Use NULL audio device"); - 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(" --rtp-port=N Base port to try for RTP"); - puts(" --add-codec=name Specify alternate codec order"); - 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(" --max-calls=N Maximum number of concurrent calls (default:4, max:255)"); - puts(""); + puts ("Usage:"); + puts (" pjsua [options]"); + puts (""); + puts ("General options:"); + puts (" --help Display this help screen"); + puts (" --version Display version info"); + puts (""); + puts ("Logging options:"); + puts (" --config-file=file Read the config/arguments from file."); + puts (" --log-file=fname Log to filename (default stderr)"); + puts (" --log-level=N Set log max level to N (0(none) to 6(trace)) (default=5)"); + puts (" --app-log-level=N Set log max level for stdout display (default=4)"); + puts (""); + 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 (""); + 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 (" --outbound=url Set the URL of outbound proxy server"); + puts (" --use-stun1=host[:port]"); + puts (" --use-stun2=host[:port] Resolve local IP with the specified STUN servers"); + puts (""); + puts ("Media Options:"); + puts (" --wb Enable wideband codecs and set clock-rate to 16KHz"); + puts (" --uwb Enable ultra-wideband codecs and set clock-rate to 32KHz"); + puts (" --null-audio Use NULL audio device"); + 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 (" --rtp-port=N Base port to try for RTP (default=4000)"); + puts (" --add-codec=name Specify alternate codec order"); + puts (" --complexity=N Specify encoding complexity (0-10, default=4)"); + puts (" --quality=N Specify encoding quality (0-10, default=4)"); + 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 (" --max-calls=N Maximum number of concurrent calls (default:4, max:255)"); + puts (""); fflush(stdout); } @@ -222,6 +224,7 @@ pj_status_t pjsua_parse_args(int argc, char *argv[]) OPT_AUTO_ANSWER, OPT_AUTO_HANGUP, OPT_AUTO_PLAY, OPT_AUTO_LOOP, OPT_AUTO_CONF, OPT_PLAY_FILE, OPT_WB, OPT_UWB, OPT_RTP_PORT, OPT_ADD_CODEC, + OPT_COMPLEXITY, OPT_QUALITY, OPT_NEXT_ACCOUNT, OPT_NEXT_CRED, OPT_MAX_CALLS, }; struct option long_options[] = { @@ -257,6 +260,8 @@ pj_status_t pjsua_parse_args(int argc, char *argv[]) { "play-file", 1, 0, OPT_PLAY_FILE}, { "rtp-port", 1, 0, OPT_RTP_PORT}, { "add-codec", 1, 0, OPT_ADD_CODEC}, + { "complexity", 1, 0, OPT_COMPLEXITY}, + { "quality", 1, 0, OPT_QUALITY}, { "next-account",0,0, OPT_NEXT_ACCOUNT}, { "next-cred", 0, 0, OPT_NEXT_CRED}, { "max-calls", 1, 0, OPT_MAX_CALLS}, @@ -496,6 +501,24 @@ pj_status_t pjsua_parse_args(int argc, char *argv[]) pjsua.codec_arg[pjsua.codec_cnt++] = pj_str(optarg); break; + case OPT_COMPLEXITY: + pjsua.complexity = my_atoi(optarg); + if (pjsua.complexity < 0 || pjsua.complexity > 10) { + PJ_LOG(1,(THIS_FILE, + "Error: invalid --complexity (expecting 0-10")); + return -1; + } + break; + + case OPT_QUALITY: + pjsua.quality = my_atoi(optarg); + if (pjsua.quality < 0 || pjsua.quality > 10) { + PJ_LOG(1,(THIS_FILE, + "Error: invalid --quality (expecting 0-10")); + return -1; + } + break; + case OPT_AUTO_ANSWER: pjsua.auto_answer = my_atoi(optarg); if (pjsua.auto_answer < 100 || pjsua.auto_answer > 699) { -- cgit v1.2.3