Added complexity and quality argument, and terminate dialog properly on failures

git-svn-id: https://svn.pjsip.org/repos/pjproject/trunk@284 74dad513-b988-da41-8d7b-12977e46ad98
This commit is contained in:
Benny Prijono 2006-03-05 11:54:02 +00:00
parent d4e0abdfc8
commit 1c2bf46593
5 changed files with 150 additions and 78 deletions

View File

@ -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);
/**

View File

@ -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; i<pjsua.max_calls; ++i) {
pjsip_tx_data *tdata;
int st_code;
pjsua_call *call;
if (pjsua.calls[i].inv == NULL)
@ -1202,7 +1238,13 @@ void pjsua_call_hangup_all()
call = &pjsua.calls[i];
if (pjsip_inv_end_session(call->inv, 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);
}

View File

@ -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);

View File

@ -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) {
if (status != PJ_SUCCESS) {
//pjsip_evsub_set_mod_data(pjsua.buddies[index].sub, pjsua.mod.id,
// NULL);
//pjsua.buddies[index].sub = NULL;
} else {
pjsip_pres_terminate(pjsua.buddies[index].sub, PJ_FALSE);
pjsua.buddies[index].sub = NULL;
pjsua_perror(THIS_FILE, "Unable to unsubscribe presence",
status);
}

View File

@ -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) {