diff --git a/channels/chan_h323.c b/channels/chan_h323.c
index 7aa271a24ab38c1313b19cbdbe078f71bbee78cc..825f6091a45e65ba333166eed6a0e27baf201ddc 100755
--- a/channels/chan_h323.c
+++ b/channels/chan_h323.c
@@ -1089,6 +1089,61 @@ if (!p) {
 }
 #endif
 
+
+/* Call-back function that gets called on transfer
+ *
+ * Returns 1 on success
+ */
+int setup_transfer_call(unsigned call_reference, const char *extension)
+{
+ 	struct oh323_pvt *p;
+ 	struct ast_channel *c = NULL;
+ 	char exten[AST_MAX_EXTENSION];
+ 	char *context;
+ 
+ 	p = find_call(call_reference);
+ 
+ 	if (!p) {
+ 		ast_log(LOG_WARNING, "No such call %d.\n", call_reference);
+ 		return -1;
+ 	}
+ 
+ 	if (!p->owner) {
+ 		ast_log(LOG_WARNING, "Call %d has no owner.\n", call_reference);
+ 		return -1;
+ 	}
+ 	
+ 	memcpy(exten, extension, sizeof(exten));
+ 
+ 	c = p->owner;
+ 	if (c && c->bridge) {
+ 		strncpy(exten, extension, sizeof(exten) - 1);
+ 		context = strchr(exten, '@');
+ 		if (context) {
+ 			*context = '\0';
+ 			context++;
+ 		} else
+ 			context = c->context;
+ 		if (!strlen(context))
+ 			context = c->bridge->context;
+ 		if (ast_exists_extension(c->bridge, context, exten, 1, c->bridge->callerid)) {
+ 			
+ 			ast_log(LOG_NOTICE, "Transfering call %s to %s@%s.\n", c->bridge->name, exten, context);
+ 			
+ 			if (!ast_async_goto(c->bridge, context, exten, 1, 1))
+ 				return 1;
+ 
+ 			ast_log(LOG_WARNING, "Failed to transfer.\n");
+ 		} else {
+ 			ast_log(LOG_WARNING, "No such extension '%s' exists.\n", exten);
+ 		}
+ 	} else {
+ 		ast_log(LOG_WARNING, "There is no call to transfer\n");
+ 	}
+ 	return 0;
+}
+
+
 /**
   * Call-back function that gets called for each rtp channel opened 
   *
@@ -1714,11 +1769,13 @@ int load_module()
 		/* Register our callback functions */
 		h323_callback_register(setup_incoming_call, 
 							   setup_outgoing_call, 
+							   setup_transfer_call,
 							   create_connection, 
 							   setup_rtp_connection, 
 							   cleanup_connection, 
 							   connection_made, send_digit);	
 	
+
 		/* start the h.323 listener */
 		if (h323_start_listener(port, bindaddr)) {
 			ast_log(LOG_ERROR, "Unable to create H323 listener.\n");
diff --git a/channels/h323/ast_h323.cpp b/channels/h323/ast_h323.cpp
index f59d086846f67cf56db34c9d517fcc981c681558..6ee771a427c443be1a45e593e3ab0f4ebe4a7f55 100755
--- a/channels/h323/ast_h323.cpp
+++ b/channels/h323/ast_h323.cpp
@@ -269,6 +269,24 @@ void MyH323EndPoint::OnClosedLogicalChannel(H323Connection & connection, const H
 	H323EndPoint::OnClosedLogicalChannel(connection, channel);
 }
 
+BOOL MyH323EndPoint::OnConnectionForwarded(H323Connection & connection,
+ 		const PString & forwardParty,
+ 		const H323SignalPDU & pdu)
+ {
+ 	if (h323debug)
+ 	cout << "       -- Call Forwarded to " << forwardParty << endl;
+ 	return FALSE;
+ }
+ 
+BOOL MyH323EndPoint::ForwardConnection(H323Connection & connection,
+ 		const PString & forwardParty,
+ 		const H323SignalPDU & pdu)
+{
+ 	if (h323debug)
+ 		cout << "       -- Forwarding call to " << forwardParty << endl;
+ 	return H323EndPoint::ForwardConnection(connection, forwardParty, pdu);
+}
+
 void MyH323EndPoint::OnConnectionEstablished(H323Connection & connection, const PString & estCallToken)
 {
 	if (h323debug)
@@ -389,6 +407,48 @@ H323Connection * MyH323EndPoint::CreateConnection(unsigned callReference, void *
 	return new MyH323Connection(*this, callReference, options);
 }
 
+H323Connection * MyH323EndPoint::SetupTransfer(const PString & token,
+ 											   const PString & callIdentity,
+ 											   const PString & remoteParty,
+ 											   PString & newToken,
+											   void * userData)
+{
+ 	PString alias;
+ 	H323TransportAddress address;
+ 	
+ 	H323Connection * connection; 
+ 
+ 	if (h323debug) {
+ 		cout << " -- Setup transfer of  " << callIdentity << ":" << endl;
+ 		cout << "	-- Call from    " << token << endl;
+ 		cout << "	-- Remote Party " << remoteParty << endl;
+ 	}
+ 
+ 	connection = FindConnectionWithLock(token);
+ 
+ 	if (connection != NULL) {
+ 		unsigned int old_call_reference = connection->GetCallReference();
+ 
+ 		if (h323debug)
+ 			cout << " -- Old call reference " << old_call_reference << endl;
+ 		connection->Unlock();
+ 
+ 		if (on_transfer_call(old_call_reference, remoteParty)) {
+ 			if (h323debug)
+ 				cout << "	-- Transfer succeded " << endl;
+ 			if (connection->ClearCall(H323Connection::EndedByCallForwarded))
+ 					return NULL;
+ 			return NULL;
+ 		}
+ 	}
+ 	if (h323debug)
+ 		cout << "	-- Transfer failed " << endl;
+ 
+ 	if (connection != NULL) {
+ 		return connection;
+ 	}
+ 	return NULL;
+}
 
 /* MyH323Connection */    
 MyH323Connection::MyH323Connection(MyH323EndPoint & ep,
@@ -734,16 +794,18 @@ void h323_debug(int flag, unsigned level)
 }
 	
 /** Installs the callback functions on behalf of the PBX application  */
-void h323_callback_register(setup_incoming_cb  ifunc, 
+void h323_callback_register(setup_incoming_cb  ifunc,
 							setup_outbound_cb  sfunc,
+							setup_transfer_cb  tfunc,
 							on_connection_cb   confunc,
 							start_logchan_cb   lfunc,
-							clear_con_cb	   clfunc,
-							con_established_cb efunc,
-							send_digit_cb	   dfunc)
+ 							clear_con_cb	   clfunc,
+ 							con_established_cb efunc,
+ 							send_digit_cb	   dfunc)
 {
 	on_incoming_call = ifunc;
 	on_outgoing_call = sfunc;
+	on_transfer_call = tfunc;
 	on_create_connection = confunc;
 	on_start_logical_channel = lfunc;
 	on_connection_cleared = clfunc;
diff --git a/channels/h323/ast_h323.h b/channels/h323/ast_h323.h
index c713a842e609233d1ad0d32a94715eea6737ee3d..9818750afb80dab832ddebcff9f97d517509ef37 100755
--- a/channels/h323/ast_h323.h
+++ b/channels/h323/ast_h323.h
@@ -111,8 +111,12 @@ class MyH323EndPoint : public H323EndPoint {
 	void OnConnectionEstablished(H323Connection &, const PString &);
 	void OnConnectionCleared(H323Connection &, const PString &);
 	H323Connection * CreateConnection(unsigned, void *);
+	H323Connection * SetupTransfer(const PString &, const PString &, const PString &, PString &, void *);
 	void SendUserTone(const PString &, char);
 	H323Capabilities GetCapabilities(void);
+	BOOL OnConnectionForwarded(H323Connection &, const PString &, const H323SignalPDU &);
+ 
+	BOOL ForwardConnection(H323Connection &, const PString &, const H323SignalPDU &);
 
 	PStringArray SupportedPrefixes;	
 	
@@ -133,14 +137,14 @@ class MyH323Connection : public H323Connection {
 	H323Channel * CreateRealTimeLogicalChannel(const H323Capability &, H323Channel::Directions, unsigned, 
 											   const H245_H2250LogicalChannelParameters *);
 	H323Connection::AnswerCallResponse OnAnswerCall(const PString &, const H323SignalPDU &, H323SignalPDU &);
+	void OnReceivedReleaseComplete(const H323SignalPDU &);
 	BOOL OnAlerting(const H323SignalPDU &, const PString &);
 	BOOL OnSendReleaseComplete(H323SignalPDU &);
 	BOOL OnReceivedSignalSetup(const H323SignalPDU &);
-	void OnReceivedReleaseComplete(const H323SignalPDU &);
 	BOOL OnReceivedFacility(const H323SignalPDU &);
 	BOOL OnSendSignalSetup(H323SignalPDU &);
 	BOOL OnStartLogicalChannel(H323Channel &);
-	BOOL OnClosingLogicalChannel(H323Channel &);
+	BOOL OnClosingLogicalChannel(H323Channel &);	
 	void SendUserInputTone(char, unsigned);
 	void OnUserInputTone(char, unsigned, unsigned, unsigned);
 	void OnUserInputString(const PString &value);
diff --git a/channels/h323/chan_h323.h b/channels/h323/chan_h323.h
index 190a8244fbd3585360dcd290e34cc98abfb921b6..c1f5a90cf54879a23f746ddc599bbc739c2d80c4 100755
--- a/channels/h323/chan_h323.h
+++ b/channels/h323/chan_h323.h
@@ -131,6 +131,11 @@ setup_incoming_cb		on_incoming_call;
 typedef int (*setup_outbound_cb)(call_details_t);
 setup_outbound_cb	on_outgoing_call; 
 
+/* This is a callback prototype function, called upon
+    a transfer. */
+typedef int (*setup_transfer_cb)(unsigned int, const char *);
+setup_transfer_cb	on_transfer_call;
+
 /* This is a callback prototype function, called when the openh323 
    OnStartLogicalChannel is invoked. */
 typedef void (*start_logchan_cb)(unsigned int, const char *, int);
@@ -164,7 +169,15 @@ extern "C" {
 	void h323_debug(int, unsigned);
 
 	/* callback function handler*/
-	void h323_callback_register(setup_incoming_cb, setup_outbound_cb, on_connection_cb, start_logchan_cb, clear_con_cb, con_established_cb, send_digit_cb);
+	void h323_callback_register(setup_incoming_cb,
+ 								setup_outbound_cb,
+ 								setup_transfer_cb,
+ 								on_connection_cb,
+ 								start_logchan_cb,
+ 								clear_con_cb,
+ 								con_established_cb,
+ 								send_digit_cb);
+
 
 	int h323_set_capability(int, int);
 	int h323_set_alias(struct oh323_alias *);