Index: /pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h
===================================================================
--- /pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h	(revision 283)
+++ /pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h	(revision 284)
@@ -186,4 +186,7 @@
     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: */
@@ -338,5 +341,5 @@
  * Hangup call.
  */
-void pjsua_call_hangup(int call_index, int code);
+void pjsua_call_hangup(int call_index);
 
 
Index: /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_call.c
===================================================================
--- /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_call.c	(revision 283)
+++ /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_call.c	(revision 284)
@@ -38,7 +38,7 @@
 {
     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;
@@ -142,5 +142,10 @@
 
 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;
@@ -160,5 +165,5 @@
     pjsip_tx_data *response = NULL;
     unsigned options = 0;
-    pjsip_inv_session *inv;
+    pjsip_inv_session *inv = NULL;
     int acc_index;
     int call_index = -1;
@@ -261,6 +266,5 @@
 
 	pjsip_dlg_respond(dlg, rdata, 500, NULL, NULL, NULL);
-
-	// TODO: Need to delete dialog
+	pjsip_dlg_terminate(dlg);
 	return PJ_TRUE;
     }
@@ -287,6 +291,5 @@
 
 	pjsip_dlg_respond(dlg, rdata, 500, NULL, NULL, NULL);
-
-	// TODO: Need to delete dialog
+	pjsip_inv_terminate(inv, 500, PJ_FALSE);
 
     } else {
@@ -723,4 +726,19 @@
 }
 
+/* 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);
+    }
+}
 
 /*
@@ -744,4 +762,9 @@
 
 	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;
 
@@ -763,4 +786,5 @@
 		     "Unable to retrieve currently active local SDP", 
 		     status);
+	call_disconnect(inv, PJSIP_SC_UNSUPPORTED_MEDIA_TYPE);
 	return;
     }
@@ -772,4 +796,5 @@
 		     "Unable to retrieve currently active remote SDP", 
 		     status);
+	call_disconnect(inv, PJSIP_SC_UNSUPPORTED_MEDIA_TYPE);
 	return;
     }
@@ -789,4 +814,5 @@
 	pjsua_perror(THIS_FILE, "Unable to create media session", 
 		     status);
+	call_disconnect(inv, PJSIP_SC_UNSUPPORTED_MEDIA_TYPE);
 	return;
     }
@@ -818,4 +844,5 @@
 	pjmedia_session_destroy(call->session);
 	call->session = NULL;
+	call_disconnect(inv, PJSIP_SC_INTERNAL_SERVER_ERROR);
 	return;
     }
@@ -910,7 +937,8 @@
  * 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,4 +951,11 @@
 	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);
@@ -1190,5 +1225,5 @@
  * Terminate all calls.
  */
-void pjsua_call_hangup_all()
+void pjsua_call_hangup_all(void)
 {
     int i;
@@ -1196,4 +1231,5 @@
     for (i=0; i<pjsua.max_calls; ++i) {
 	pjsip_tx_data *tdata;
+	int st_code;
 	pjsua_call *call;
 
@@ -1203,5 +1239,11 @@
 	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);
Index: /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_core.c
===================================================================
--- /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_core.c	(revision 283)
+++ /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_core.c	(revision 284)
@@ -73,6 +73,9 @@
     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: */
@@ -615,5 +618,6 @@
 	    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",
Index: /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_pres.c
===================================================================
--- /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_pres.c	(revision 283)
+++ /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_pres.c	(revision 284)
@@ -116,5 +116,5 @@
     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);
@@ -145,4 +145,5 @@
 		     status);
 	pj_list_erase(uapres);
+	pjsip_pres_terminate(sub, PJ_FALSE);
 	return PJ_FALSE;
     }
@@ -169,4 +170,5 @@
 		     status);
 	pj_list_erase(uapres);
+	pjsip_pres_terminate(sub, PJ_FALSE);
 	return PJ_FALSE;
     }
@@ -328,4 +330,5 @@
 	pjsua_perror(THIS_FILE, "Unable to create presence client", 
 		     status);
+	pjsip_dlg_terminate(dlg);
 	return;
     }
@@ -336,4 +339,5 @@
     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", 
@@ -344,4 +348,5 @@
     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", 
@@ -349,6 +354,4 @@
 	return;
     }
-
-    PJ_TODO(DESTROY_DIALOG_ON_ERROR);
 }
 
@@ -374,11 +377,8 @@
 	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;
-
-    } else {
+    if (status != PJ_SUCCESS) {
+
+	pjsip_pres_terminate(pjsua.buddies[index].sub, PJ_FALSE);
+	pjsua.buddies[index].sub = NULL;
 	pjsua_perror(THIS_FILE, "Unable to unsubscribe presence", 
 		     status);
Index: /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_settings.c
===================================================================
--- /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_settings.c	(revision 283)
+++ /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_settings.c	(revision 284)
@@ -46,59 +46,61 @@
 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);
 }
@@ -223,4 +225,5 @@
 	   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,
     };
@@ -258,4 +261,6 @@
 	{ "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},
@@ -495,4 +500,22 @@
 	case OPT_ADD_CODEC:
 	    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;
 
