diff --git a/channels/chan_h323.c b/channels/chan_h323.c
index 6f45566172c25c6bb5ee2966778edebcb29f82c3..5cc7cddb0294776dcf261a43394ad677a6e4c998 100644
--- a/channels/chan_h323.c
+++ b/channels/chan_h323.c
@@ -647,9 +647,13 @@ static int oh323_call(struct ast_channel *c, char *dest, int timeout)
 	} else
 		pvt->options.redirect_reason = -1;
 
+	pvt->options.transfer_capability = c->transfercapability;
+
 	/* indicate that this is an outgoing call */
 	pvt->outgoing = 1;
 
+	if (option_verbose > 2)
+		ast_verbose(VERBOSE_PREFIX_3 "Requested transfer capability: 0x%.2x - %s\n", c->transfercapability, ast_transfercapability2str(c->transfercapability));
 	if (h323debug)
 		ast_log(LOG_DEBUG, "Placing outgoing call to %s, %d/%d\n", called_addr, pvt->options.dtmfcodec[0], pvt->options.dtmfcodec[1]);
 	ast_mutex_unlock(&pvt->lock);
@@ -1083,6 +1087,8 @@ static struct ast_channel *__oh323_new(struct oh323_pvt *pvt, int state, const c
 		if (!ast_strlen_zero(pvt->exten) && strcmp(pvt->exten, "s")) {
 			ch->cid.cid_dnid = strdup(pvt->exten);
 		}
+		if (pvt->cd.transfer_capability >= 0)
+			ch->transfercapability = pvt->cd.transfer_capability;
 		ast_setstate(ch, state);
 		if (state != AST_STATE_DOWN) {
 			if (ast_pbx_start(ch)) {
@@ -1108,6 +1114,7 @@ static struct oh323_pvt *oh323_alloc(int callid)
 	}
 	memset(pvt, 0, sizeof(struct oh323_pvt));
 	pvt->cd.redirect_reason = -1;
+	pvt->cd.transfer_capability = -1;
 	/* Ensure the call token is allocated for outgoing call */
 	if (!callid) {
 		if ((pvt->cd).call_token == NULL) {
diff --git a/channels/h323/ast_h323.cxx b/channels/h323/ast_h323.cxx
index f574482c61013f90952f49c4bf952701bca316b1..8d316c7c47e7b07524a55337b53e2eedaa74808d 100644
--- a/channels/h323/ast_h323.cxx
+++ b/channels/h323/ast_h323.cxx
@@ -554,6 +554,7 @@ MyH323Connection::MyH323Connection(MyH323EndPoint & ep, unsigned callReference,
 	dtmfMode = 0;
 	dtmfCodec[0] = dtmfCodec[1] = (RTP_DataFrame::PayloadTypes)0;
 	redirect_reason = -1;
+	transfer_capability = -1;
 #ifdef TUNNELLING
 	tunnelOptions = remoteTunnelOptions = 0;
 #endif
@@ -735,6 +736,9 @@ void MyH323Connection::SetCallOptions(void *o, BOOL isIncoming)
 		}
 		cid_presentation = opts->presentation;
 		cid_ton = opts->type_of_number;
+		if (opts->transfer_capability >= 0) {
+			transfer_capability = opts->transfer_capability;
+		}
 	}
 	tunnelOptions = opts->tunnelOptions;
 }
@@ -768,6 +772,8 @@ void MyH323Connection::SetCallDetails(void *callDetails, const H323SignalPDU &se
 		PString redirect_number;
 		unsigned redirect_reason;
 		unsigned plan, type, screening, presentation;
+		Q931::InformationTransferCapability capability;
+		unsigned transferRate, codingStandard, userInfoLayer1;
 
 		/* Fetch presentation and type information about calling party's number */
 		if (setupPDU.GetQ931().GetCallingPartyNumber(sourceName, &plan, &type, &presentation, &screening, 0, 0)) {
@@ -795,13 +801,20 @@ void MyH323Connection::SetCallDetails(void *callDetails, const H323SignalPDU &se
 		GetSignallingChannel()->GetRemoteAddress().GetIpAndPort(Ip, sourcePort);
 		cd->sourceIp = strdup((const char *)Ip.AsString());
 
-		if(setupPDU.GetQ931().GetRedirectingNumber(redirect_number, NULL, NULL, NULL, NULL, &redirect_reason, 0, 0, 0)) {
+		if (setupPDU.GetQ931().GetRedirectingNumber(redirect_number, NULL, NULL, NULL, NULL, &redirect_reason, 0, 0, 0)) {
 			cd->redirect_number = strdup((const char *)redirect_number);
 			cd->redirect_reason = redirect_reason;
 		}
 		else
 			cd->redirect_reason = -1;
 
+		/* Fetch Q.931's transfer capability */
+		if (((Q931 &)setupPDU.GetQ931()).GetBearerCapabilities(capability, transferRate, &codingStandard, &userInfoLayer1))
+			cd->transfer_capability = ((unsigned int)capability & 0x1f) | (codingStandard << 5);
+		else
+			cd->transfer_capability = 0x00;	/* ITU coding of Speech */
+
+		/* Don't show local username as called party name */
 		SetDisplayName(cd->call_dest_e164);
 	}
 
@@ -1228,6 +1241,9 @@ BOOL MyH323Connection::OnSendSignalSetup(H323SignalPDU & setupPDU)
 		setupPDU.GetQ931().SetIE(Q931::RedirectingNumberIE, IE);
 	}
 
+	if (transfer_capability)
+		setupPDU.GetQ931().SetBearerCapabilities((Q931::InformationTransferCapability)(transfer_capability & 0x1f), 1, ((transfer_capability >> 5) & 3));
+
 	SetCallDetails(&cd, setupPDU, FALSE);
 
 	int res = on_outgoing_call(&cd);
diff --git a/channels/h323/ast_h323.h b/channels/h323/ast_h323.h
index 339329560b56d267d3c60a4416adf19d17b67983..39af427ae46f58af079389688ca8bd29fe30209b 100644
--- a/channels/h323/ast_h323.h
+++ b/channels/h323/ast_h323.h
@@ -109,6 +109,7 @@ public:
 	int cid_ton;
 	PString rdnis;
 	int redirect_reason;
+	int transfer_capability;
 
 	WORD sessionId;
 	BOOL bridging;
diff --git a/channels/h323/chan_h323.h b/channels/h323/chan_h323.h
index 378df1edc7447048ad9da9860aa30450b3568f79..62b670fda01acabeb7d65a3386aae34ffc34cc70 100644
--- a/channels/h323/chan_h323.h
+++ b/channels/h323/chan_h323.h
@@ -52,6 +52,7 @@ typedef struct call_options {
 	int				redirect_reason;
 	int				presentation;
 	int				type_of_number;
+	int				transfer_capability;
 	int				fastStart;
 	int				h245Tunneling;
 	int				silenceSuppression;
@@ -118,6 +119,7 @@ typedef struct call_details {
 	int redirect_reason;
 	int presentation;
 	int type_of_number;
+	int transfer_capability;
 	char *sourceIp;
 } call_details_t;