summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2006-03-05 11:54:02 +0000
committerBenny Prijono <bennylp@teluu.com>2006-03-05 11:54:02 +0000
commit185de1159231659d85b2ed4f18298176da51f666 (patch)
tree7814991aacb59fb6fa593d033a362709991d9b76
parentcb88a08734906fe0e47fef54752d5928ae9d45ac (diff)
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
-rw-r--r--pjsip/include/pjsua-lib/pjsua.h5
-rw-r--r--pjsip/src/pjsua-lib/pjsua_call.c64
-rw-r--r--pjsip/src/pjsua-lib/pjsua_core.c8
-rw-r--r--pjsip/src/pjsua-lib/pjsua_pres.c18
-rw-r--r--pjsip/src/pjsua-lib/pjsua_settings.c133
5 files changed, 150 insertions, 78 deletions
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; 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);
}
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) {