Index: channels/chan_gtalk.c
===================================================================
--- channels/chan_gtalk.c	(revision 115340)
+++ channels/chan_gtalk.c	(working copy)
@@ -166,6 +166,7 @@
 /* Forward declarations */
 static struct ast_channel *gtalk_request(const char *type, int format, void *data, int *cause);
 static int gtalk_digit(struct ast_channel *ast, char digit, unsigned int duration);
+static int gtalk_sendtext(struct ast_channel *ast, const char *text);
 static int gtalk_digit_begin(struct ast_channel *ast, char digit);
 static int gtalk_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
 static int gtalk_call(struct ast_channel *ast, char *dest, int timeout);
@@ -194,6 +195,7 @@
 	.description = "Gtalk Channel Driver",
 	.capabilities = AST_FORMAT_AUDIO_MASK,
 	.requester = gtalk_request,
+	.send_text = gtalk_sendtext,
 	.send_digit_begin = gtalk_digit_begin,
 	.send_digit_end = gtalk_digit_end,
 	.bridge = ast_rtp_bridge,
@@ -1456,6 +1458,14 @@
 	return res;
 }
 
+static int gtalk_sendtext(struct ast_channel *chan, const char *text)
+{
+	struct gtalk_pvt *p = chan->tech_pvt;
+	struct aji_client *client = p->parent->connection;
+	ast_aji_send_chat(client, p->them, text);
+	return 0;
+}
+
 static int gtalk_digit_begin(struct ast_channel *chan, char digit)
 {
 	return gtalk_digit(chan, digit, 0);
Index: res/res_jabber.c
===================================================================
--- res/res_jabber.c	(revision 115340)
+++ res/res_jabber.c	(working copy)
@@ -69,6 +69,7 @@
 static void aji_client_destroy(struct aji_client *obj);
 static int aji_send_exec(struct ast_channel *chan, void *data);
 static int aji_status_exec(struct ast_channel *chan, void *data);
+static int aji_recv_exec(struct ast_channel *chan, void *data);
 static int aji_is_secure(struct aji_client *client);
 static int aji_start_tls(struct aji_client *client);
 static int aji_tls_handshake(struct aji_client *client);
@@ -145,6 +146,14 @@
 "             In order, Online, Chatty, Away, XAway, DND, Offline\n" 
 "             If not in roster variable will = 7\n";
 
+static char *app_ajirecv = "JabberReceive";
+
+static char *ajirecv_synopsis = "JabberReceive(Variable)";
+
+static char *ajirecv_descrip =
+"JabberReceive(Variable)\n"
+"  Variable - Variable to store message in.\n";
+
 struct aji_client_container clients;
 struct aji_capabilities *capabilities = NULL;
 
@@ -729,6 +738,34 @@
 	return IKS_OK;
 }
 
+ /*!
+ * \brief Dial plan function to receive a message.
+ * \param channel, and data, data is sender, variable.
+ * \return received text or NULL.
+ */
+static int aji_recv_exec(struct ast_channel *chan, void *data)
+{
+	char message[AST_MAX_EXTENSION];
+	int timeout = 10000;
+	char *buf = NULL, *variable = NULL;
+
+	if (data) {
+		variable = ast_strdupa((char *) data);
+	} else {
+		ast_log(LOG_ERROR, "Out of memory\n");
+		return -1;
+	}
+
+	buf = ast_recvtext(chan, timeout);
+	/* return if we timed out */
+	if (!buf)
+		return -1;
+
+	ast_copy_string(message, buf, sizeof(message));
+	pbx_builtin_setvar_helper(chan, variable, message);
+	return 0;
+}
+
 /*!
  * \brief the debug loop.
  * \param data void
@@ -1435,7 +1472,15 @@
 static void aji_handle_message(struct aji_client *client, ikspak *pak)
 {
 	struct aji_message *insert, *tmp;
+	struct ast_channel *chan = NULL;
+	char ccid[AST_MAX_EXTENSION];
+	char *from;
+	char *uid = NULL;
+	struct ast_frame f = { AST_FRAME_TEXT, };
 	int flag = 0;
+
+	if (option_debug)
+		ast_log(LOG_DEBUG, "client %s received a message\n", client->name);
 	
 	if (!(insert = ast_calloc(1, sizeof(*insert))))
 		return;
@@ -1444,8 +1489,32 @@
 		insert->message = ast_strdup(iks_find_cdata(pak->x, "body"));
 	if (pak->id)
 		ast_copy_string(insert->id, pak->id, sizeof(insert->message));
-	if (pak->from)
-		insert->from = ast_strdup(pak->from->full);
+	if (pak->from){
+		/* insert will furtherly be added to message list */
+ 		insert->from = ast_strdup(pak->from->full);
+		/* local copy will be automatically freed as a stack variable*/
+		from = ast_strdupa(pak->from->full);
+		uid = strsep(&from, "@");
+		sprintf(ccid, "Gtalk/%s", uid);
+
+		if (option_debug) {
+			ast_log(LOG_DEBUG, "message comes from %s\n", insert->from);
+			ast_log(LOG_DEBUG, "Looking for channel %s\n", ccid);
+		}
+		chan = ast_get_channel_by_name_prefix_locked(ccid, strlen(ccid));
+		if (option_debug) {
+			ast_log(LOG_NOTICE, "chan was %s \n", chan ? "FOUND" : "NOT FOUND");
+		}		
+		if (chan) {
+			f.datalen = strlen(insert->message);
+			f.data = (void *) insert->message;
+			if (option_debug)
+				ast_log(LOG_DEBUG, "Queuing text frame to %s\n", chan->name);
+			ast_queue_frame(chan, &f);
+			ast_channel_unlock(chan);
+		}
+	}
+
 	AST_LIST_LOCK(&client->messages);
 	AST_LIST_TRAVERSE_SAFE_BEGIN(&client->messages, tmp, list) {
 		if (flag) {
@@ -2985,6 +3054,7 @@
 			"Sends a message to a Jabber Client", mandescr_jabber_send);
 	ast_register_application(app_ajisend, aji_send_exec, ajisend_synopsis, ajisend_descrip);
 	ast_register_application(app_ajistatus, aji_status_exec, ajistatus_synopsis, ajistatus_descrip);
+	ast_register_application(app_ajirecv, aji_recv_exec, ajirecv_synopsis, ajirecv_descrip);
 	ast_cli_register_multiple(aji_cli, sizeof(aji_cli) / sizeof(struct ast_cli_entry));
 	ast_custom_function_register(&jabberstatus_function);
 
