Index: /pjproject/trunk/pjsip-apps/src/pjsua/pjsua_app.c
===================================================================
--- /pjproject/trunk/pjsip-apps/src/pjsua/pjsua_app.c	(revision 1470)
+++ /pjproject/trunk/pjsip-apps/src/pjsua/pjsua_app.c	(revision 1471)
@@ -1910,12 +1910,13 @@
     puts("|  H  Hold call                |  u  Unsubscribe presence | ru  Unregister    |");
     puts("|  v  re-inVite (release hold) |  t  ToGgle Online status |  >  Cycle next ac.|");
-    puts("|  ]  Select next dialog       |  T  Set online status    |  <  Cycle prev ac.|");
-    puts("|  [  Select previous dialog   +--------------------------+-------------------+");
+    puts("|  U  send UPDATE              |  T  Set online status    |  <  Cycle prev ac.|");
+    puts("| ],[ Select next/prev call    +--------------------------+-------------------+");
     puts("|  x  Xfer call                |      Media Commands:     |  Status & Config: |");
     puts("|  X  Xfer with Replaces       |                          |                   |");
-    puts("|  #  Send DTMF string         | cl  List ports           |  d  Dump status   |");
-    puts("| dq  Dump curr. call quality  | cc  Connect port         | dd  Dump detailed |");
-    puts("|                              | cd  Disconnect port      | dc  Dump config   |");
-    puts("|  S  Send arbitrary REQUEST   |  V  Adjust audio Volume  |  f  Save config   |");
+    puts("|  #  Send RFC 2833 DTMF       | cl  List ports           |  d  Dump status   |");
+    puts("|  *  Send DTMF with INFO      | cc  Connect port         | dd  Dump detailed |");
+    puts("| dq  Dump curr. call quality  | cd  Disconnect port      | dc  Dump config   |");
+    puts("|                              |  V  Adjust audio Volume  |  f  Save config   |");
+    puts("|  S  Send arbitrary REQUEST   | Cp  Codec priorities     |  f  Save config   |");
     puts("+------------------------------+--------------------------+-------------------+");
     puts("|  q  QUIT                  sleep N: console sleep for N ms                   |");
@@ -2190,4 +2191,56 @@
 
 /*
+ * Change codec priorities.
+ */
+static void manage_codec_prio(void)
+{
+    pjsua_codec_info c[32];
+    unsigned i, count = PJ_ARRAY_SIZE(c);
+    char input[32];
+    char *codec, *prio;
+    pj_str_t id;
+    int new_prio;
+    pj_status_t status;
+
+    printf("List of codecs:\n");
+
+    pjsua_enum_codecs(c, &count);
+    for (i=0; i<count; ++i) {
+	printf("  %d\t%.*s\n", c[i].priority, (int)c[i].codec_id.slen,
+			       c[i].codec_id.ptr);
+    }
+
+    puts("");
+    puts("Enter codec name and its new priority (e.g. \"speex/16000 200\"), empty to cancel:");
+
+    printf("Codec name and priority: ");
+    fgets(input, sizeof(input), stdin);
+    if (input[0]=='\r' || input[0]=='\n') {
+	puts("Done");
+	return;
+    }
+
+    codec = strtok(input, " \t\r\n");
+    prio = strtok(NULL, " \r\n");
+
+    if (!codec || !prio) {
+	puts("Invalid input");
+	return;
+    }
+
+    new_prio = atoi(prio);
+    if (new_prio < 0) 
+	new_prio = 0;
+    else if (new_prio > PJMEDIA_CODEC_PRIO_HIGHEST) 
+	new_prio = PJMEDIA_CODEC_PRIO_HIGHEST;
+
+    status = pjsua_codec_set_priority(pj_cstr(&id, codec), 
+				      (pj_uint8_t)new_prio);
+    if (status != PJ_SUCCESS)
+	pjsua_perror(THIS_FILE, "Error setting codec priority", status);
+}
+
+
+/*
  * Main "user interface" loop.
  */
@@ -2612,4 +2665,23 @@
 	    break;
 
+	case 'U':
+	    /*
+	     * Send UPDATE
+	     */
+	    if (current_call != -1) {
+		
+		pjsua_call_update(current_call, 0, NULL);
+
+	    } else {
+		PJ_LOG(3,(THIS_FILE, "No current call"));
+	    }
+	    break;
+
+	case 'C':
+	    if (menuin[1] == 'p') {
+		manage_codec_prio();
+	    }
+	    break;
+
 	case 'x':
 	    /*
Index: /pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h
===================================================================
--- /pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h	(revision 1470)
+++ /pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h	(revision 1471)
@@ -2766,4 +2766,17 @@
 					 const pjsua_msg_data *msg_data);
 
+/**
+ * Send UPDATE request.
+ *
+ * @param call_id	Call identification.
+ * @param options	Must be zero for now.
+ * @param msg_data	Optional message components to be sent with
+ *			the request.
+ *
+ * @return		PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_call_update(pjsua_call_id call_id,
+				       unsigned options,
+				       const pjsua_msg_data *msg_data);
 
 /**
Index: /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_call.c
===================================================================
--- /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_call.c	(revision 1470)
+++ /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_call.c	(revision 1471)
@@ -1272,4 +1272,68 @@
     if (status != PJ_SUCCESS) {
 	pjsua_perror(THIS_FILE, "Unable to send re-INVITE", status);
+	pjsip_dlg_dec_lock(dlg);
+	return status;
+    }
+
+    pjsip_dlg_dec_lock(dlg);
+
+    return PJ_SUCCESS;
+}
+
+
+/*
+ * Send UPDATE request.
+ */
+PJ_DEF(pj_status_t) pjsua_call_update( pjsua_call_id call_id,
+				       unsigned options,
+				       const pjsua_msg_data *msg_data)
+{
+    pjmedia_sdp_session *sdp;
+    pjsip_tx_data *tdata;
+    pjsua_call *call;
+    pjsip_dialog *dlg;
+    pj_status_t status;
+
+    PJ_UNUSED_ARG(options);
+
+    PJ_ASSERT_RETURN(call_id>=0 && call_id<(int)pjsua_var.ua_cfg.max_calls,
+		     PJ_EINVAL);
+
+    status = acquire_call("pjsua_call_update()", call_id, &call, &dlg);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    /* Init media channel */
+    status = pjsua_media_channel_init(call->index, PJSIP_ROLE_UAC);
+    if (status != PJ_SUCCESS) {
+	pjsua_perror(THIS_FILE, "Error initializing media channel", status);
+	pjsip_dlg_dec_lock(dlg);
+	return PJSIP_ESESSIONSTATE;
+    }
+
+    /* Create SDP */
+    status = pjsua_media_channel_create_sdp(call->index, call->inv->pool, &sdp);
+    if (status != PJ_SUCCESS) {
+	pjsua_perror(THIS_FILE, "Unable to get SDP from media endpoint", 
+		     status);
+	pjsip_dlg_dec_lock(dlg);
+	return status;
+    }
+
+    /* Create re-INVITE with new offer */
+    status = pjsip_inv_update(call->inv, NULL, sdp, &tdata);
+    if (status != PJ_SUCCESS) {
+	pjsua_perror(THIS_FILE, "Unable to create UPDATE request", status);
+	pjsip_dlg_dec_lock(dlg);
+	return status;
+    }
+
+    /* Add additional headers etc */
+    pjsua_process_msg_data( tdata, msg_data);
+
+    /* Send the request */
+    status = pjsip_inv_send_msg( call->inv, tdata);
+    if (status != PJ_SUCCESS) {
+	pjsua_perror(THIS_FILE, "Unable to send UPDAT Erequest", status);
 	pjsip_dlg_dec_lock(dlg);
 	return status;
