Index: res/res_jabber.c
===================================================================
--- res/res_jabber.c	(revision 49135)
+++ res/res_jabber.c	(working copy)
@@ -61,6 +61,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 void aji_log_hook(void *data, const char *xmpp, size_t size, int is_incoming);
 static int aji_act_hook(void *data, int type, iks *node);
 static void aji_handle_iq(struct aji_client *client, iks *node);
@@ -159,6 +160,15 @@
 "             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(Jabber, Variable)";
+
+static char *ajirecv_descrip =
+"JabberReceive(Jabber, Variable)\n"
+"  Jabber - Client or transport Asterisk uses to connect to Jabber\n"
+"  Variable - Variable to store message in.\n";
+
 struct aji_client_container clients;
 
 struct aji_capabilities *capabilities;
@@ -376,7 +386,7 @@
 	}
 	buddy = ASTOBJ_CONTAINER_FIND(&client->buddies, (resource)?screenname:jid);
 	if (!buddy) {
-		ast_log(LOG_WARNING, "Could not find Buddy in list.\n");
+		ast_log(LOG_WARNING, "Could not find buddy %s in list.\n",(resource) ? screenname : jid);
 		return -1;
 	}
 	r = aji_find_resource(buddy, resource);
@@ -385,6 +395,7 @@
 	}
 	if(!r){
 		ast_log(LOG_NOTICE, "Resource %s of buddy %s not found \n", resource, screenname);
+		return -1;
 	}
 	stat = r->status;
 	sprintf(status, "%d", stat);
@@ -430,6 +441,53 @@
 }
 
 /*!
+ * \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)
+{
+	struct aji_client *client = NULL;
+	char message[AST_MAX_EXTENSION];
+	int timeout = 10000;
+	char *s = NULL, *sender = NULL, *buf = NULL, *variable = NULL;
+
+	if (data) {
+		s = ast_strdupa((char *) data);
+		if (s) {
+			sender = strsep(&s, "|");
+			if (sender && (sender[0] != '\0')) {
+				variable = s;
+			} else {
+				ast_log(LOG_ERROR, "Bad arguments\n");
+				return -1;
+			}
+		}
+	} else {
+		ast_log(LOG_ERROR, "Out of memory\n");
+		return -1;
+	}
+
+	if (!(client = ast_aji_get_client(sender))) {
+		ast_log(LOG_WARNING, "Could not find any jabber client named %s.\n", sender);
+		return -1;
+	}
+	if(!&client->buddies) {
+		ast_log(LOG_WARNING, "No buddies for connection.\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 aji_client structure, xml data as string, size of string, direction of packet, 1 for inbound 0 for outbound.
  */
@@ -626,8 +684,6 @@
 		break;
 	case IKS_PAK_MESSAGE:
 		aji_handle_message(client, pak);
-		if (option_debug)
-			ast_log(LOG_DEBUG, "JABBER: I Don't know what to do with you MESSAGE\n");
 		break;
 	case IKS_PAK_PRESENCE:
 		aji_handle_presence(client, pak);
@@ -1090,7 +1146,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(struct aji_message))))
 		return;
@@ -1099,8 +1163,31 @@
 		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)
+	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) {
@@ -2408,6 +2495,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_log(LOG_NOTICE, "res_jabber.so loaded.\n");
