Mercurial > pidgin
changeset 30657:e30865b62859
Initial support for msnp16, based on patch by Masca.
References #8247.
author | Elliott Sales de Andrade <qulogic@pidgin.im> |
---|---|
date | Tue, 01 Dec 2009 22:13:30 +0000 |
parents | dbd030780f75 |
children | ed838ad00173 |
files | libpurple/protocols/msn/msn.h libpurple/protocols/msn/notification.c libpurple/protocols/msn/notification.h libpurple/protocols/msn/session.c libpurple/protocols/msn/session.h libpurple/protocols/msn/state.c libpurple/protocols/msn/switchboard.c |
diffstat | 7 files changed, 139 insertions(+), 25 deletions(-) [+] |
line wrap: on
line diff
--- a/libpurple/protocols/msn/msn.h Mon Nov 30 05:59:57 2009 +0000 +++ b/libpurple/protocols/msn/msn.h Tue Dec 01 22:13:30 2009 +0000 @@ -52,9 +52,9 @@ #define MSN_SERVER "messenger.hotmail.com" #define MSN_HTTPCONN_SERVER "gateway.messenger.hotmail.com" #define MSN_PORT 1863 -#define WLM_PROT_VER 15 +#define WLM_PROT_VER 16 -#define WLM_MAX_PROTOCOL 15 +#define WLM_MAX_PROTOCOL 16 #define WLM_MIN_PROTOCOL 15 #define MSN_TYPING_RECV_TIMEOUT 6 @@ -137,15 +137,14 @@ } MsnClientVerId; -#define MSN_CLIENT_ID_VERSION MSN_CLIENT_VER_7_0 +#define MSN_CLIENT_ID_VERSION MSN_CLIENT_VER_9_0 #define MSN_CLIENT_ID_CAPABILITIES (MSN_CLIENT_CAP_PACKET|MSN_CLIENT_CAP_INK_GIF|MSN_CLIENT_CAP_VOICEIM) +#define MSN_CLIENT_ID_EXT_CAPS (0) #define MSN_CLIENT_ID \ ((MSN_CLIENT_ID_VERSION << 24) | \ (MSN_CLIENT_ID_CAPABILITIES)) -#define MSN_CLIENT_EXT_ID 0 - gboolean msn_email_is_valid(const char *passport); void msn_act_id(PurpleConnection *gc, const char *entry); void msn_send_privacy(PurpleConnection *gc);
--- a/libpurple/protocols/msn/notification.c Mon Nov 30 05:59:57 2009 +0000 +++ b/libpurple/protocols/msn/notification.c Tue Dec 01 22:13:30 2009 +0000 @@ -161,7 +161,10 @@ msn_session_set_login_step(session, MSN_LOGIN_STEP_AUTH_END); - msn_cmdproc_send(cmdproc, "USR", "SSO S %s %s", ticket, response); + if (session->protocol_ver >= 16) + msn_cmdproc_send(cmdproc, "USR", "SSO S %s %s %s", ticket, response, session->guid); + else + msn_cmdproc_send(cmdproc, "USR", "SSO S %s %s", ticket, response); } static void @@ -1676,6 +1679,86 @@ cmd->payload_len = atoi(cmd->params[1]); } +void +msn_notification_send_uux(MsnSession *session, const char *payload) +{ + MsnTransaction *trans; + MsnCmdProc *cmdproc; + size_t len = strlen(payload); + + cmdproc = session->notification->cmdproc; + purple_debug_misc("msn", "Sending UUX command with payload: %s\n", payload); + trans = msn_transaction_new(cmdproc, "UUX", "%" G_GSIZE_FORMAT, len); + msn_transaction_set_payload(trans, payload, len); + msn_cmdproc_send_trans(cmdproc, trans); +} + +void msn_notification_send_uux_endpointdata(MsnSession *session) +{ + xmlnode *epDataNode; + xmlnode *capNode; + char *caps; + char *payload; + int length; + + epDataNode = xmlnode_new("EndpointData"); + + capNode = xmlnode_new_child(epDataNode, "Capabilities"); + caps = g_strdup_printf("%d:%02d", MSN_CLIENT_ID_CAPABILITIES, MSN_CLIENT_ID_EXT_CAPS); + xmlnode_insert_data(capNode, caps, -1); + g_free(caps); + + payload = xmlnode_to_str(epDataNode, &length); + + msn_notification_send_uux(session, payload); + + xmlnode_free(epDataNode); + g_free(payload); +} + +void msn_notification_send_uux_private_endpointdata(MsnSession *session) +{ + xmlnode *private; + xmlnode *epname; + xmlnode *idle; + xmlnode *client_type; + xmlnode *state; + char *payload; + int length; + + private = xmlnode_new("PrivateEndPointData"); + + /* TODO: "Pidgin" is a temp EndPointName.. we must use hostid or some.*/ + epname = xmlnode_new_child(private, "EpName"); + xmlnode_insert_data(epname, "Pidgin", -1); + + idle = xmlnode_new_child(private, "Idle"); + xmlnode_insert_data(idle, "false", -1); + + /* TODO: support different client types */ + /* ClientType info (from amsn guys): + 0: None + 1: Computer + 2: Website + 3: Mobile / none + 4: Xbox / phone /mobile + 9: MsnGroup + 32: Email member, currently Yahoo! + */ + client_type = xmlnode_new_child(private, "ClientType"); + xmlnode_insert_data(client_type, "1", -1); + + state = xmlnode_new_child(private, "State"); + xmlnode_insert_data(state, msn_state_get_text(msn_state_from_account(session->account)), -1); + + payload = xmlnode_to_str(private, &length); + + msn_notification_send_uux(session, payload); + + xmlnode_free(private); + g_free(payload); +} + /************************************************************************** * Message Types **************************************************************************/
--- a/libpurple/protocols/msn/notification.h Mon Nov 30 05:59:57 2009 +0000 +++ b/libpurple/protocols/msn/notification.h Tue Dec 01 22:13:30 2009 +0000 @@ -82,6 +82,12 @@ void msn_notification_disconnect(MsnNotification *notification); void msn_notification_dump_contact(MsnSession *session); +void msn_notification_send_uux(MsnSession *session, const char *payload); + +void msn_notification_send_uux_endpointdata(MsnSession *session); + +void msn_notification_send_uux_private_endpointdata(MsnSession *session); + /** * Closes a notification. *
--- a/libpurple/protocols/msn/session.c Mon Nov 30 05:59:57 2009 +0000 +++ b/libpurple/protocols/msn/session.c Tue Dec 01 22:13:30 2009 +0000 @@ -22,6 +22,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ #include "msn.h" +#include "msnutils.h" #include "session.h" #include "notification.h" #include "oim.h" @@ -47,6 +48,8 @@ session->protocol_ver = WLM_PROT_VER; + session->guid = rand_guid(); + return session; } @@ -90,6 +93,7 @@ msn_userlist_destroy(session->userlist); g_free(session->psm); + g_free(session->guid); g_free(session->abch_cachekey); #if 0 g_free(session->blocked_text); @@ -448,6 +452,11 @@ msn_session_sync_users(session); } + if (session->protocol_ver >= 16) { + /* TODO: Send this when updating status instead? */ + msn_notification_send_uux_endpointdata(session); + /*msn_notification_send_uux_private_endpointdata(session);*/ + } msn_change_status(session); }
--- a/libpurple/protocols/msn/session.h Mon Nov 30 05:59:57 2009 +0000 +++ b/libpurple/protocols/msn/session.h Tue Dec 01 22:13:30 2009 +0000 @@ -126,6 +126,7 @@ GHashTable *soap_table; guint soap_cleanup_handle; + char *guid; }; /**
--- a/libpurple/protocols/msn/state.c Mon Nov 30 05:59:57 2009 +0000 +++ b/libpurple/protocols/msn/state.c Tue Dec 01 22:13:30 2009 +0000 @@ -26,6 +26,7 @@ #include "core.h" #include "msn.h" +#include "notification.h" #include "state.h" static const char *away_text[] = @@ -42,10 +43,6 @@ N_("Available") }; -/* Local Function Prototype*/ -static char *msn_build_psm(const char *psmstr,const char *mediastr, - const char *guidstr); - /* * WLM media PSM info build prcedure * @@ -55,7 +52,7 @@ * <CurrentMedia>\0Office\01\0Office Message\0Office App Name\0</CurrentMedia>" */ static char * -msn_build_psm(const char *psmstr,const char *mediastr, const char *guidstr) +msn_build_psm(const char *psmstr,const char *mediastr, const char *guidstr, guint protocol_ver) { xmlnode *dataNode,*psmNode,*mediaNode,*guidNode; char *result; @@ -81,6 +78,12 @@ } xmlnode_insert_child(dataNode, guidNode); + if (protocol_ver >= 16) { + /* TODO: What is this for? */ + xmlnode *ddpNode = xmlnode_new("DDP"); + xmlnode_insert_child(dataNode, ddpNode); + } + result = xmlnode_to_str(dataNode, &length); xmlnode_free(dataNode); return result; @@ -252,8 +255,6 @@ PurpleAccount *account; PurplePresence *presence; PurpleStatus *status; - MsnCmdProc *cmdproc; - MsnTransaction *trans; char *payload; const char *statusline; gchar *statusline_stripped, *media = NULL; @@ -262,7 +263,6 @@ g_return_if_fail(session->notification != NULL); account = session->account; - cmdproc = session->notification->cmdproc; /* Get the PSM string from Purple's Status Line */ presence = purple_account_get_presence(account); @@ -273,13 +273,11 @@ statusline_stripped = purple_markup_strip_html(statusline); media = create_media_string(presence); g_free(session->psm); - session->psm = msn_build_psm(statusline_stripped, media, NULL); + session->psm = msn_build_psm(statusline_stripped, media, session->protocol_ver >= 16 ? session->guid : NULL, session->protocol_ver); payload = session->psm; - purple_debug_misc("msn", "Sending UUX command with payload: %s\n", payload); - trans = msn_transaction_new(cmdproc, "UUX", "%" G_GSIZE_FORMAT, strlen(payload)); - msn_transaction_set_payload(trans, payload, strlen(payload)); - msn_cmdproc_send_trans(cmdproc, trans); + + msn_notification_send_uux(session, payload); g_free(statusline_stripped); g_free(media); @@ -327,11 +325,16 @@ if (!session->logged_in) return; + msn_set_psm(session); + msnobj = msn_user_get_object(user); if (msnobj == NULL) { - msn_cmdproc_send(cmdproc, "CHG", "%s %d", state_text, caps); + if (session->protocol_ver >= 16) + msn_cmdproc_send(cmdproc, "CHG", "%s %u:%02u 0", state_text, caps, MSN_CLIENT_ID_EXT_CAPS); + else + msn_cmdproc_send(cmdproc, "CHG", "%s %d", state_text, caps); } else { @@ -339,12 +342,15 @@ msnobj_str = msn_object_to_string(msnobj); - msn_cmdproc_send(cmdproc, "CHG", "%s %d %s", state_text, - caps, purple_url_encode(msnobj_str)); + if (session->protocol_ver >= 16) + msn_cmdproc_send(cmdproc, "CHG", "%s %u:%02u %s", state_text, + caps, MSN_CLIENT_ID_EXT_CAPS, purple_url_encode(msnobj_str)); + else + msn_cmdproc_send(cmdproc, "CHG", "%s %d %s", state_text, + caps, purple_url_encode(msnobj_str)); g_free(msnobj_str); } - msn_set_psm(session); } const char *
--- a/libpurple/protocols/msn/switchboard.c Mon Nov 30 05:59:57 2009 +0000 +++ b/libpurple/protocols/msn/switchboard.c Tue Dec 01 22:13:30 2009 +0000 @@ -949,6 +949,7 @@ MsnTransaction *trans; MsnCmdProc *cmdproc; PurpleAccount *account; + char *username; cmdproc = servconn->cmdproc; g_return_if_fail(cmdproc != NULL); @@ -957,24 +958,33 @@ swboard = cmdproc->data; g_return_if_fail(swboard != NULL); + if (servconn->session->protocol_ver >= 16) + username = g_strdup(purple_account_get_username(account)); + else + username = g_strdup_printf("%s;{%s}", + purple_account_get_username(account), + servconn->session->guid); + if (msn_switchboard_is_invited(swboard)) { swboard->empty = FALSE; trans = msn_transaction_new(cmdproc, "ANS", "%s %s %s", - purple_account_get_username(account), + username, swboard->auth_key, swboard->session_id); } else { trans = msn_transaction_new(cmdproc, "USR", "%s %s", - purple_account_get_username(account), + username, swboard->auth_key); } msn_transaction_set_error_cb(trans, ans_usr_error); msn_transaction_set_data(trans, swboard); msn_cmdproc_send_trans(cmdproc, trans); + + g_free(username); } static void