changeset 19777:1b6c631012d9

[gaim-migrate @ 17034] middle version for oim send not stable,don't use it! committed by MaYuan<mayuan2006@gmail.com> committer: Ethan Blanton <elb@pidgin.im>
author Ma Yuan <mayuan2006@gmail.com>
date Sat, 26 Aug 2006 03:25:00 +0000
parents 509383ef25f8
children a8d00b8dae40
files src/protocols/msn/contact.c src/protocols/msn/msn.c src/protocols/msn/oim.c src/protocols/msn/oim.h src/protocols/msn/slpcall.c src/protocols/msn/soap.c src/protocols/msn/user.c
diffstat 7 files changed, 307 insertions(+), 100 deletions(-) [+]
line wrap: on
line diff
--- a/src/protocols/msn/contact.c	Thu Aug 24 16:38:30 2006 +0000
+++ b/src/protocols/msn/contact.c	Sat Aug 26 03:25:00 2006 +0000
@@ -117,7 +117,7 @@
 	int list_op =0;
 	char * passport;
 	xmlnode * node,*body,*response,*result,*services,*service,*memberships;
-	xmlnode *membershipnode,*members,*member,*passportNode,*role;
+	xmlnode *membershipnode,*members,*member,*passportNode;
 
 	session = contact->session;
 	gaim_debug_misc("xml","parse contact list:{%s}\nsize:%d\n",contact->soapconn->body,contact->soapconn->body_len);
@@ -143,9 +143,13 @@
 	gaim_debug_misc("xml","memberships{%p},name:%s\n",memberships,memberships->name);
 	for(membershipnode = xmlnode_get_child(memberships, "Membership"); membershipnode;
 					membershipnode = xmlnode_get_next_twin(membershipnode)){
-		role = xmlnode_get_child(membershipnode,"MemberRole");
-		list_op = msn_get_memberrole(xmlnode_get_data(role));
-		gaim_debug_misc("memberrole","role:%s,list_op:%d\n",xmlnode_get_data(role),list_op);
+		xmlnode *roleNode;
+		char *role;
+		roleNode = xmlnode_get_child(membershipnode,"MemberRole");
+		role=xmlnode_get_data(roleNode);
+		list_op = msn_get_memberrole(role);
+		gaim_debug_misc("memberrole","role:%s,list_op:%d\n",role,list_op);
+		g_free(role);
 		members = xmlnode_get_child(membershipnode,"Members");
 		for(member = xmlnode_get_child(members, "Member"); member;
 				member = xmlnode_get_next_twin(member)){
@@ -160,9 +164,11 @@
 				typeNode = xmlnode_get_child(member,"Type");
 				type = xmlnode_get_data(typeNode);
 				gaim_debug_misc("Passport","name:%s,type:%s\n",passport,type);
+				g_free(type);
 
 				user = msn_userlist_find_add_user(session->userlist,passport,NULL);
 				msn_got_lst_user(session, user, list_op, NULL);
+				g_free(passport);
 			}
 			if(!g_strcasecmp(xmlnode_get_attrib(member,"type"),"PhoneMember")){
 			}
@@ -174,6 +180,7 @@
 				gaim_debug_info("Email","name:%s,list_op:%d\n",passport,list_op);
 				user = msn_userlist_find_add_user(session->userlist,passport,NULL);
 				msn_got_lst_user(session,user,list_op,NULL);
+				g_free(passport);
 			}
 		}
 	}
@@ -268,18 +275,20 @@
 			continue;
 		}
 
-		gaim_debug_misc("MsnContact","group_id:%s name:%s\n",group_id,group_name);
+		gaim_debug_misc("MsnAB","group_id:%s name:%s\n",group_id,group_name);
 		if ((gaim_find_group(group_name)) == NULL){
 			GaimGroup *g = gaim_group_new(group_name);
 			gaim_blist_add_group(g, NULL);
 		}
+		g_free(group_id);
+		g_free(group_name);
 	}
 	/*add a default No group to set up the no group Membership*/
 	group_id = g_strdup(MSN_INDIVIDUALS_GROUP_ID);
 	group_name = g_strdup(MSN_INDIVIDUALS_GROUP_NAME);
 	msn_group_new(session->userlist,group_id , group_name);
 	if (group_id != NULL){
-		gaim_debug_misc("MsnContact","group_id:%s name:%s,value:%d\n",group_id,group_name,*group_name=='\0');
+		gaim_debug_misc("MsnAB","group_id:%s name:%s,value:%d\n",group_id,group_name,*group_name=='\0');
 		if ((gaim_find_group(group_name)) == NULL){
 			GaimGroup *g = gaim_group_new(group_name);
 			gaim_blist_add_group(g, NULL);
@@ -293,7 +302,7 @@
 	group_name = g_strdup(MSN_NON_IM_GROUP_NAME);
 	msn_group_new(session->userlist,group_id , group_name);
 	if (group_id != NULL){
-		gaim_debug_misc("MsnContact","group_id:%s name:%s,value:%d\n",group_id,group_name,*group_name=='\0');
+		gaim_debug_misc("MsnAB","group_id:%s name:%s,value:%d\n",group_id,group_name,*group_name=='\0');
 		if ((gaim_find_group(group_name)) == NULL){
 			GaimGroup *g = gaim_group_new(group_name);
 			gaim_blist_add_group(g, NULL);
@@ -335,38 +344,44 @@
 				if(!strcmp(msnEnabled,"true")){
 					emailNode = xmlnode_get_child(contactEmailNode,"email");
 					passport = xmlnode_get_data(emailNode);
-					gaim_debug_info("Ma Yuan","Yahoo User %s\n",passport);
+					gaim_debug_info("MsnAB","Yahoo User %s\n",passport);
 					break;
 				}
+				g_free(msnEnabled);
 			}
 		}else{
 			passport = xmlnode_get_data(passportName);
 		}
 
 		displayName = xmlnode_get_child(contactInfo,"displayName");
-		if(displayName == NULL)
-			Name = passport;
-		else
+		if(displayName == NULL){
+			Name = g_strdup(passport);
+		}else{
 			Name =xmlnode_get_data(displayName);	
+		}
 
-		gaim_debug_misc("contact","name:%s,Id:{%s},display:{%s}\n",
+		gaim_debug_misc("MsnAB","name:%s,Id:{%s},display:{%s}\n",
 						passport,
-						xmlnode_get_data(contactId),
+						uid,
 						Name);
 
 		user = msn_userlist_find_add_user(session->userlist, passport,Name);
 		msn_user_set_uid(user,uid);
 		msn_user_set_type(user,msn_get_user_type(type));
 		user->list_op |= MSN_LIST_FL_OP;
+		g_free(Name);
+		g_free(passport);
+		g_free(uid);
+		g_free(type);
 
-		gaim_debug_misc("MsnContact","\n");
 		groupIds = xmlnode_get_child(contactInfo,"groupIds");
 		if(groupIds){
 			for(guid = xmlnode_get_child(groupIds, "guid");guid;
 							guid = xmlnode_get_next_twin(guid)){
 				group_id = xmlnode_get_data(guid);
 				msn_user_add_group_id(user,group_id);
-				gaim_debug_misc("contact","guid:%s\n",group_id);
+				gaim_debug_misc("MsnAB","guid:%s\n",group_id);
+				g_free(group_id);
 			}
 		}else{
 			group_id = g_strdup(MSN_INDIVIDUALS_GROUP_ID);
--- a/src/protocols/msn/msn.c	Thu Aug 24 16:38:30 2006 +0000
+++ b/src/protocols/msn/msn.c	Sat Aug 26 03:25:00 2006 +0000
@@ -824,65 +824,81 @@
 	account = gaim_connection_get_account(gc);
 
 	msn_import_html(message, &msgformat, &msgtext);
+	if(msn_user_is_online(account, who)){
+		/*User online,then send Online Instant Message*/
 
-	if (strlen(msgtext) + strlen(msgformat) + strlen(VERSION) > 1564)
-	{
+		if (strlen(msgtext) + strlen(msgformat) + strlen(VERSION) > 1564)
+		{
+			g_free(msgformat);
+			g_free(msgtext);
+
+			return -E2BIG;
+		}
+
+		msg = msn_message_new_plain(msgtext);
+		msg->remote_user = g_strdup(who);
+		msn_message_set_attr(msg, "X-MMS-IM-Format", msgformat);
+
 		g_free(msgformat);
 		g_free(msgtext);
 
-		return -E2BIG;
-	}
+		gaim_debug_info("MaYuan","prepare to send online Message\n");
+		if (g_ascii_strcasecmp(who, gaim_account_get_username(account)))
+		{
+			MsnSession *session;
+			MsnSwitchBoard *swboard;
 
-	msg = msn_message_new_plain(msgtext);
-	msg->remote_user = g_strdup(who);
-	msn_message_set_attr(msg, "X-MMS-IM-Format", msgformat);
-
-	g_free(msgformat);
-	g_free(msgtext);
+			session = gc->proto_data;
+			if(strstr(who,"yahoo") != NULL){
+				gaim_debug_info("MaYuan","send to Yahoo!\n");
+				uum_send_msg(session,msg);
+			}else{
+				gaim_debug_info("MaYuan","send via switchboard\n");
+				swboard = msn_session_get_swboard(session, who, MSN_SB_FLAG_IM);
+				msn_switchboard_send_msg(swboard, msg, TRUE);
+			}
+		}
+		else
+		{
+			char *body_str, *body_enc, *pre, *post;
+			const char *format;
+			/*
+			 * In MSN, you can't send messages to yourself, so
+			 * we'll fake like we received it ;)
+			 */
+			body_str = msn_message_to_string(msg);
+			body_enc = g_markup_escape_text(body_str, -1);
+			g_free(body_str);
 
-	gaim_debug_info("MaYuan","prepare to send...\n");
-	if (g_ascii_strcasecmp(who, gaim_account_get_username(account)))
-	{
+			format = msn_message_get_attr(msg, "X-MMS-IM-Format");
+			msn_parse_format(format, &pre, &post);
+			body_str = g_strdup_printf("%s%s%s", pre ? pre :  "",
+									   body_enc ? body_enc : "", post ? post : "");
+			g_free(body_enc);
+			g_free(pre);
+			g_free(post);
+
+			serv_got_typing_stopped(gc, who);
+			serv_got_im(gc, who, body_str, flags, time(NULL));
+			g_free(body_str);
+		}
+
+		msn_message_destroy(msg);
+	}else	{
+		/*send Offline Instant Message*/
 		MsnSession *session;
-		MsnSwitchBoard *swboard;
-
+		MsnOim *oim;
+		char *friendname;
+		
+		gaim_debug_info("MaYuan","prepare to send offline Message\n");		
 		session = gc->proto_data;
-		if(strstr(who,"yahoo") != NULL){
-			gaim_debug_info("MaYuan","send to Yahoo!\n");
-			uum_send_msg(session,msg);
-		}else{
-			gaim_debug_info("MaYuan","send via switchboard\n");
-			swboard = msn_session_get_swboard(session, who, MSN_SB_FLAG_IM);
-			msn_switchboard_send_msg(swboard, msg, TRUE);
-		}
+		oim = session->oim;
+		friendname = g_strdup_printf("=?utf-8?B?Y2xpZW50?=");
+		msn_oim_prep_send_msg_info(oim,
+			gaim_account_get_username(account),friendname,who,
+			msg);
+		msn_oim_send_msg(oim);
 	}
-	else
-	{
-		char *body_str, *body_enc, *pre, *post;
-		const char *format;
-		/*
-		 * In MSN, you can't send messages to yourself, so
-		 * we'll fake like we received it ;)
-		 */
-		body_str = msn_message_to_string(msg);
-		body_enc = g_markup_escape_text(body_str, -1);
-		g_free(body_str);
-
-		format = msn_message_get_attr(msg, "X-MMS-IM-Format");
-		msn_parse_format(format, &pre, &post);
-		body_str = g_strdup_printf("%s%s%s", pre ? pre :  "",
-								   body_enc ? body_enc : "", post ? post : "");
-		g_free(body_enc);
-		g_free(pre);
-		g_free(post);
-
-		serv_got_typing_stopped(gc, who);
-		serv_got_im(gc, who, body_str, flags, time(NULL));
-		g_free(body_str);
-	}
-
-	msn_message_destroy(msg);
-
 	return 1;
 }
 
--- a/src/protocols/msn/oim.c	Thu Aug 24 16:38:30 2006 +0000
+++ b/src/protocols/msn/oim.c	Sat Aug 26 03:25:00 2006 +0000
@@ -26,11 +26,13 @@
 #include "msn.h"
 #include "soap.h"
 #include "oim.h"
+#include "msn-utils.h"
 
 /*Local Function Prototype*/
 static void msn_oim_post_single_get_msg(MsnOim *oim,const char *msgid);
 void msn_oim_retrieve_connect_init(MsnSoapConn *soapconn);
 void msn_oim_send_connect_init(MsnSoapConn *soapconn);
+void msn_oim_free_send_req(MsnOimSendReq *req);
 
 /*new a OIM object*/
 MsnOim *
@@ -41,9 +43,13 @@
 	oim = g_new0(MsnOim, 1);
 	oim->session = session;
 	oim->retrieveconn = msn_soap_new(session,oim,1);
+	
 	oim->oim_list	= NULL;
 	oim->sendconn = msn_soap_new(session,oim,1);
-
+	oim->run_id = rand_guid();
+	oim->challenge = NULL;
+	oim->send_queue = g_queue_new();
+	oim->send_seq = 1;
 	return oim;
 }
 
@@ -51,14 +57,74 @@
 void
 msn_oim_destroy(MsnOim *oim)
 {
+	MsnOimSendReq *request;
+	
 	msn_soap_destroy(oim->retrieveconn);
 	msn_soap_destroy(oim->sendconn);
+	g_free(oim->run_id);
+	g_free(oim->challenge);
+	
+	while((request = g_queue_pop_head(oim->send_queue)) != NULL){
+		msn_oim_free_send_req(request);
+	}
+	g_queue_free(oim->send_queue);
+	
 	g_free(oim);
 }
 
+MsnOimSendReq *
+msn_oim_new_send_req(char *from_member,
+				char*friendname,char* to_member,
+				gint send_seq,
+				char *msg)
+{
+	MsnOimSendReq *request;
+	
+	request = g_new0(MsnOimSendReq, 1);
+	request->from_member =g_strdup(from_member);
+	request->friendname = g_strdup(friendname);
+	request->to_member = g_strdup(to_member);
+	request->send_seq = send_seq;
+	request->oim_msg= g_strdup(msg);
+	return request;
+}
+
+void
+msn_oim_free_send_req(MsnOimSendReq *req)
+{
+	g_free(req->from_member);
+	g_free(req->friendname);
+	g_free(req->to_member);
+	g_free(req->oim_msg);
+	
+	g_free(req);
+}
+
 /****************************************
  * OIM send SOAP request
  * **************************************/
+/*encode the message to OIM Message Format*/
+char * 
+msn_oim_msg_to_str(MsnOim *oim,char *body)
+{
+	char *oim_body;
+	char *oim_base64,*oim_base16;
+	
+	gaim_debug_info("MaYuan","encode OIM Message...\n");	
+	gaim_debug_info("MaYuan","runid:{%s}\n",oim->run_id);	
+	gaim_debug_info("MaYuan","body:{%s}\n",body);	
+	oim_base64 = gaim_base64_encode((const guchar *)body, strlen(body));
+	gaim_debug_info("MaYuan","encode body:{%s}\n",oim_base64);	
+	oim_base16 = gaim_base16_encode((const guchar *)body, strlen(body));
+	gaim_debug_info("MaYuan","encode body:{%s}\n",oim_base16);	
+
+	oim_body = g_strdup_printf(MSN_OIM_MSG_TEMPLATE,
+				oim->run_id,oim->send_seq,oim_base64);
+	gaim_debug_info("MaYuan","start base64 encode\n",body);	
+
+	return oim_body;
+}
+
 /*oim SOAP server login error*/
 static void
 msn_oim_send_error_cb(GaimSslConnection *gsc, GaimSslErrorType error, void *data)
@@ -88,14 +154,54 @@
 	g_return_if_fail(session != NULL);
 }
 
+void
+msn_oim_send_process(MsnOim *oim,char *body,int len)
+{
+	xmlnode *responseNode,*bodyNode,*faultNode;
+	xmlnode *detailNode,*challengeNode;
+	char *challenge;
+
+	responseNode = xmlnode_from_str(body,len);
+	g_return_if_fail(responseNode != NULL);
+	bodyNode = xmlnode_get_child(responseNode,"Body");
+	faultNode = xmlnode_get_child(bodyNode,"Fault");
+	if(faultNode == NULL){
+		/*Send OK! return*/
+		MsnOimSendReq *request;
+		
+		xmlnode_free(responseNode);
+		request = g_queue_pop_head(oim->send_queue);
+		msn_oim_free_send_req(request);
+		/*send next buffered Offline Message*/
+		msn_soap_post(oim->sendconn,NULL,msn_oim_send_connect_init);
+		return;
+	}
+	/*get the challenge,and repost it*/
+	detailNode = xmlnode_get_child(faultNode, "detail");
+	challengeNode = xmlnode_get_child(detailNode,"LockKeyChallenge");
+//	gaim_debug_info("MaYuan","challenge:{%s}\n",challenge);
+
+	gaim_debug_info("MaYuan","prepare to dup the challenge\n");
+	g_free(oim->challenge);
+	oim->challenge = xmlnode_get_data(challengeNode);
+	gaim_debug_info("MaYuan","lockkey:{%s}\n",oim->challenge);
+
+	xmlnode_free(responseNode);
+
+	/*repost the send*/
+	gaim_debug_info("MaYuan","prepare to repost the send...\n");
+	msn_oim_send_msg(oim);
+}
+
 static void
 msn_oim_send_read_cb(gpointer data, GaimSslConnection *gsc,
 				 GaimInputCondition cond)
 {
 	MsnSoapConn * soapconn = data;	
-	MsnOim * msnoim;
+	MsnOim * oim;
 
 	gaim_debug_info("MaYuan","read buffer:{%s}\n",soapconn->body);
+	msn_oim_send_process(oim,soapconn->body,soapconn->body_len);
 }
 
 static void
@@ -107,43 +213,68 @@
 //	msn_soap_read_cb(data,source,cond);
 }
 
-/*pose single message to oim server*/
+void
+msn_oim_prep_send_msg_info(MsnOim *oim,
+					char *membername,char*friendname,char *tomember,
+					char * msg)
+{
+	MsnOimSendReq *request;
+
+	request = msn_oim_new_send_req(membername,friendname,tomember,oim->send_seq,msg);
+	g_queue_push_tail(oim->send_queue,request);
+}
+
+/*post send single message request to oim server*/
 void 
-msn_oim_send_single_msg(MsnOim *oim,char * msg)
+msn_oim_send_msg(MsnOim *oim)
 {
 	MsnSoapReq *soap_request;
-	const char *soap_body,*t,*p;
-
+	MsnOimSendReq *oim_request;
+	char *soap_body,*mspauth;
+	char *msg_body;
+	char buf[33];
+	
+	oim_request = g_queue_pop_head(oim->send_queue);
+	if(oim_request == NULL){
+		return;
+	}
 	gaim_debug_info("MaYuan","send single OIM Message\n");
-	oim->sendconn->login_path = g_strdup(MSN_OIM_SEND_URL);
-	oim->sendconn->soap_action = g_strdup(MSN_OIM_SEND_SOAP_ACTION);
-	t = oim->session->passport_info.t;
-	p = oim->session->passport_info.p;
-#if 0
-	oimsoapbody = g_strdup_printf(MSN_OIM_SEND_TEMPLATE,
-					membername,
-					friendname,
-					tomember,
+	mspauth = g_strdup_printf("t=%s&amp;p=%s",
+		oim->session->passport_info.t,
+		oim->session->passport_info.p
+		);
+	gaim_debug_info("MaYuan","get mspauth...\n");	
+	if(oim->challenge != NULL){
+		msn_handle_chl(oim->challenge, buf);
+	}else{
+		g_queue_push_head(oim->send_queue,oim_request);
+		buf[0]='\0';
+	}
+	gaim_debug_info("MaYuan","get challenge...\n");	
+
+	msg_body = msn_oim_msg_to_str(oim, oim_request->oim_msg);
+	gaim_debug_info("MaYuan","get body...\n");	
+	soap_body = g_strdup_printf(MSN_OIM_SEND_TEMPLATE,
+					oim_request->from_member,
+					oim_request->friendname,
+					oim_request->to_member,
 					mspauth,
-					prod_id,
-					lock_key,
-					msg_num,
-					msg
+					MSNP13_WLM_PRODUCT_ID,
+					buf,
+					oim_request->send_seq,
+					msg_body
 					);
-#endif
+	gaim_debug_info("MaYuan","post body...\n");
 	soap_request = msn_soap_request_new(MSN_OIM_SEND_HOST,
 					MSN_OIM_SEND_URL,MSN_OIM_SEND_SOAP_ACTION,
 					soap_body,
 					msn_oim_send_read_cb,
 					msn_oim_send_written_cb);
-	msn_soap_post(oim->sendconn,soap_request,msn_oim_send_connect_init);
-}
+	g_free(mspauth);
+	g_free(msg_body);
+	g_free(soap_body);
 
-void msn_oim_send_msg(MsnOim *oim,char *msg)
-{
-	if(msn_soap_connected(oim->sendconn) == -1){
-	}
-	
+	msn_soap_post(oim->sendconn,soap_request,msn_oim_send_connect_init);
 }
 
 /****************************************
@@ -304,6 +435,7 @@
 	msgNode = xmlnode_get_child(responseNode,"GetMessageResult");
 	msg_data = xmlnode_get_data(msgNode);
 	msg_str = g_strdup(msg_data);
+	g_free(msg_data);
 	gaim_debug_info("OIM","msg:{%s}\n",msg_str);
 	msn_oim_report_to_user(oim,msg_str);
 
@@ -342,14 +474,14 @@
 void
 msn_parse_oim_msg(MsnOim *oim,const char *xmlmsg)
 {
-	xmlnode *mdNode,*mNode,*INode,*nNode,*ENode,*rtNode;
+	xmlnode *mdNode,*mNode,*ENode,*INode,*rtNode,*nNode;
 	char *passport,*rTime,*msgid,*nickname;
 
 	mdNode = xmlnode_from_str(xmlmsg, strlen(xmlmsg));
 	for(mNode = xmlnode_get_child(mdNode, "M"); mNode;
 					mNode = xmlnode_get_next_twin(mNode)){
-		INode = xmlnode_get_child(mNode,"E");
-		passport = xmlnode_get_data(INode);
+		ENode = xmlnode_get_child(mNode,"E");
+		passport = xmlnode_get_data(ENode);
 		INode = xmlnode_get_child(mNode,"I");
 		msgid = xmlnode_get_data(INode);
 		rtNode = xmlnode_get_child(mNode,"RT");
@@ -360,6 +492,10 @@
 
 		oim->oim_list = g_list_append(oim->oim_list,msgid);
 		msn_oim_post_single_get_msg(oim,msgid);
+		g_free(passport);
+		g_free(msgid);
+		g_free(rTime);
+		g_free(nickname);
 	}
 }
 
--- a/src/protocols/msn/oim.h	Thu Aug 24 16:38:30 2006 +0000
+++ b/src/protocols/msn/oim.h	Sat Aug 26 03:25:00 2006 +0000
@@ -67,18 +67,26 @@
 "</soap:Envelope>"
 
 /*OIM Send SOAP Template*/
+#define MSN_OIM_MSG_TEMPLATE "MIME-Version: 1.0\n"\
+	"Content-Type: text/plain; charset=UTF-8\n"\
+	"Content-Transfer-Encoding: base64\n"\
+	"X-OIM-Message-Type: OfflineMessage\n"\
+	"X-OIM-Run-Id: {%s}\n"\
+	"X-OIM-Sequence-Num: %d\n\n"\
+	"%s"
+
 #define MSN_OIM_SEND_HOST	"ows.messenger.msn.com"
 #define MSN_OIM_SEND_URL	"/OimWS/oim.asmx"
 #define MSN_OIM_SEND_SOAP_ACTION	"http://messenger.msn.com/ws/2004/09/oim/Store"
 #define MSN_OIM_SEND_TEMPLATE "<?xml version=\"1.0\" encoding=\"utf-8\"?>"\
 "<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"\
 	"<soap:Header>"\
-		"<From memberName=\"%s\" friendlyName=\"%s\" xml:lang=\"en-US\" proxy=\"MSNMSGR\" xmlns=\"http://messenger.msn.com/ws/2004/09/oim/\" msnpVer=\"MSNP13\" buildVer=\"8.0.0689\"/>"\
+		"<From memberName=\"%s\" friendlyName=\"%s\" xml:lang=\"en-US\" proxy=\"MSNMSGR\" xmlns=\"http://messenger.msn.com/ws/2004/09/oim/\" msnpVer=\"MSNP14\" buildVer=\"8.0.0792\"/>"\
 		"<To memberName=\"%s\" xmlns=\"http://messenger.msn.com/ws/2004/09/oim/\"/>"\
 		"<Ticket passport=\"%s\" appid=\"%s\" lockkey=\"%s\" xmlns=\"http://messenger.msn.com/ws/2004/09/oim/\"/>"\
 		"<Sequence xmlns=\"http://schemas.xmlsoap.org/ws/2003/03/rm\">"\
 			"<Identifier xmlns=\"http://schemas.xmlsoap.org/ws/2002/07/utility\">http://messenger.msn.com</Identifier>"\
-			"<MessageNumber>%s</MessageNumber>"\
+			"<MessageNumber>%d</MessageNumber>"\
 		"</Sequence>"\
 	"</soap:Header>"\
 	"<soap:Body>"\
@@ -87,6 +95,17 @@
 	"</soap:Body>"\
 "</soap:Envelope>"
 
+typedef struct _MsnOimSendReq MsnOimSendReq;
+
+struct _MsnOimSendReq
+{
+	char *from_member;
+	char *friendname;
+	char *to_member;
+	char *oim_msg;
+	gint send_seq;
+};
+
 typedef struct _MsnOim MsnOim;
 
 struct _MsnOim
@@ -97,7 +116,10 @@
 	GList * oim_list;
 
 	MsnSoapConn *sendconn;
-	gint	LockKeyChallenge;
+	char *challenge;
+	char *run_id;
+	gint send_seq;
+	GQueue *send_queue;
 };
 
 /****************************************************
@@ -109,6 +131,13 @@
 
 void msn_parse_oim_msg(MsnOim *oim,const char *xmlmsg);
 
+/*Send OIM Message*/
+void msn_oim_prep_send_msg_info(MsnOim *oim,
+					char *membername,char*friendname,char *tomember,
+					char * msg);
+
+void msn_oim_send_msg(MsnOim *oim);
+
 /*get the OIM message*/
 void msn_oim_get_msg(MsnOim *oim);
 
--- a/src/protocols/msn/slpcall.c	Thu Aug 24 16:38:30 2006 +0000
+++ b/src/protocols/msn/slpcall.c	Sat Aug 26 03:25:00 2006 +0000
@@ -33,7 +33,7 @@
  * Util
  **************************************************************************/
 
-static char *
+char *
 rand_guid()
 {
 	return g_strdup_printf("%4X%4X-%4X-%4X-%4X-%4X%4X%4X",
--- a/src/protocols/msn/soap.c	Thu Aug 24 16:38:30 2006 +0000
+++ b/src/protocols/msn/soap.c	Sat Aug 26 03:25:00 2006 +0000
@@ -324,7 +324,8 @@
 
 		msn_session_set_error(session, MSN_ERROR_SERV_UNAVAILABLE, error);
 	}
-	else if (strstr(soapconn->read_buf, "HTTP/1.1 200 OK"))
+	else if ((strstr(soapconn->read_buf, "HTTP/1.1 200 OK"))
+		||(strstr(soapconn->read_buf, "HTTP/1.1 500")))
 	{
 			/*OK! process the SOAP body*/
 			body_start = (char *)g_strstr_len(soapconn->read_buf, soapconn->read_len,"\r\n\r\n");
--- a/src/protocols/msn/user.c	Thu Aug 24 16:38:30 2006 +0000
+++ b/src/protocols/msn/user.c	Sat Aug 26 03:25:00 2006 +0000
@@ -298,6 +298,16 @@
 	b->proto_data = user;
 }
 
+/*check if the msn user is online*/
+gboolean
+msn_user_is_online(GaimAccount *account, const char *name)
+{
+	GaimBuddy *buddy;
+
+	buddy =gaim_find_buddy(account,name);
+	return GAIM_BUDDY_IS_ONLINE(buddy);
+}
+
 void
 msn_user_remove_group_id(MsnUser *user, const char * id)
 {