# HG changeset patch # User andrew.victor@mxit.com # Date 1294437065 0 # Node ID b8d9329dda4a39a436e74b4478359b0efc03f118 # Parent 607ad979a753e87a2ae4c8ad1f952d6a3f548731 The initial protocol infrastructure for MXit Voice/Video support. (Currently disabled with compile-time flag) diff -r 607ad979a753 -r b8d9329dda4a libpurple/protocols/mxit/Makefile.am --- a/libpurple/protocols/mxit/Makefile.am Fri Jan 07 19:56:19 2011 +0000 +++ b/libpurple/protocols/mxit/Makefile.am Fri Jan 07 21:51:05 2011 +0000 @@ -33,7 +33,9 @@ roster.c \ roster.h \ splashscreen.c \ - splashscreen.h + splashscreen.h \ + voicevideo.c \ + voicevideo.h AM_CFLAGS = $(st) diff -r 607ad979a753 -r b8d9329dda4a libpurple/protocols/mxit/Makefile.mingw --- a/libpurple/protocols/mxit/Makefile.mingw Fri Jan 07 19:56:19 2011 +0000 +++ b/libpurple/protocols/mxit/Makefile.mingw Fri Jan 07 21:51:05 2011 +0000 @@ -51,7 +51,8 @@ profile.c \ protocol.c \ roster.c \ - splashscreen.c + splashscreen.c \ + voicevideo.c OBJECTS = $(C_SRC:%.c=%.o) diff -r 607ad979a753 -r b8d9329dda4a libpurple/protocols/mxit/mxit.c --- a/libpurple/protocols/mxit/mxit.c Fri Jan 07 19:56:19 2011 +0000 +++ b/libpurple/protocols/mxit/mxit.c Fri Jan 07 21:51:05 2011 +0000 @@ -37,6 +37,7 @@ #include "filexfer.h" #include "actions.h" #include "multimx.h" +#include "voicevideo.h" #ifdef MXIT_LINK_CLICK @@ -719,8 +720,8 @@ NULL, /* attention_types */ sizeof( PurplePluginProtocolInfo ), /* struct_size */ mxit_get_text_table, /* get_account_text_table */ - NULL, /* initiate_media */ - NULL, /* get_media_caps */ + mxit_media_initiate, /* initiate_media */ + mxit_media_caps, /* get_media_caps */ mxit_get_moods, /* get_moods */ NULL, /* set_public_alias */ NULL /* get_public_alias */ diff -r 607ad979a753 -r b8d9329dda4a libpurple/protocols/mxit/mxit.h --- a/libpurple/protocols/mxit/mxit.h Fri Jan 07 19:56:19 2011 +0000 +++ b/libpurple/protocols/mxit/mxit.h Fri Jan 07 21:51:05 2011 +0000 @@ -111,7 +111,6 @@ /* define this to enable the link clicking support */ #define MXIT_LINK_CLICK - #ifdef MXIT_LINK_CLICK #define MXIT_LINK_PREFIX "gopher://" #define MXIT_LINK_KEY "MXIT" @@ -141,6 +140,9 @@ guint http_handler; /* HTTP connection handler */ void* http_out_req; /* HTTP outstanding request */ + /* other servers */ + char voip_server[HOST_NAME_MAX]; /* voice/video server */ + /* client */ struct login_data* logindata; char* encpwd; /* encrypted password */ diff -r 607ad979a753 -r b8d9329dda4a libpurple/protocols/mxit/protocol.c --- a/libpurple/protocols/mxit/protocol.c Fri Jan 07 19:56:19 2011 +0000 +++ b/libpurple/protocols/mxit/protocol.c Fri Jan 07 21:51:05 2011 +0000 @@ -37,6 +37,7 @@ #include "login.h" #include "formcmds.h" #include "http.h" +#include "voicevideo.h" #define MXIT_MS_OFFSET 3 @@ -638,9 +639,16 @@ const char* locale; char data[CP_MAX_PACKET]; int datalen; + unsigned int features = MXIT_CP_FEATURES; locale = purple_account_get_string( session->acc, MXIT_CONFIG_LOCALE, MXIT_DEFAULT_LOCALE ); + /* Voice and Video supported */ + if (mxit_audio_enabled() && mxit_video_enabled()) + features |= (MXIT_CF_VOICE | MXIT_CF_VIDEO); + else if (mxit_audio_enabled()) + features |= MXIT_CF_VOICE; + /* convert the packet to a byte stream */ datalen = snprintf( data, sizeof( data ), "ms=%s%c%s%c%i%c%s%c" /* "ms"=password\1version\1maxreplyLen\1name\1 */ @@ -648,7 +656,7 @@ "%s%c%i%c%s%c%s", /* dc\1features\1dialingcode\1locale */ session->encpwd, CP_FLD_TERM, MXIT_CP_VERSION, CP_FLD_TERM, CP_MAX_FILESIZE, CP_FLD_TERM, profile->nickname, CP_FLD_TERM, profile->birthday, CP_FLD_TERM, ( profile->male ) ? 1 : 0, CP_FLD_TERM, MXIT_DEFAULT_LOC, CP_FLD_TERM, MXIT_CP_CAP, CP_FLD_TERM, - session->distcode, CP_FLD_TERM, MXIT_CP_FEATURES, CP_FLD_TERM, session->dialcode, CP_FLD_TERM, locale + session->distcode, CP_FLD_TERM, features, CP_FLD_TERM, session->dialcode, CP_FLD_TERM, locale ); /* queue packet for transmission */ @@ -663,13 +671,20 @@ */ void mxit_send_login( struct MXitSession* session ) { - const char* splashId; - const char* locale; - char data[CP_MAX_PACKET]; - int datalen; + const char* splashId; + const char* locale; + char data[CP_MAX_PACKET]; + int datalen; + unsigned int features = MXIT_CP_FEATURES; locale = purple_account_get_string( session->acc, MXIT_CONFIG_LOCALE, MXIT_DEFAULT_LOCALE ); + /* Voice and Video supported */ + if (mxit_audio_enabled() && mxit_video_enabled()) + features |= (MXIT_CF_VOICE | MXIT_CF_VIDEO); + else if (mxit_audio_enabled()) + features |= MXIT_CF_VOICE; + /* convert the packet to a byte stream */ datalen = snprintf( data, sizeof( data ), "ms=%s%c%s%c%i%c" /* "ms"=password\1version\1getContacts\1 */ @@ -677,7 +692,7 @@ "%s%c%s%c" /* dialingcode\1locale\1 */ "%i%c%i%c%i", /* maxReplyLen\1protocolVer\1lastRosterUpdate */ session->encpwd, CP_FLD_TERM, MXIT_CP_VERSION, CP_FLD_TERM, 1, CP_FLD_TERM, - MXIT_CP_CAP, CP_FLD_TERM, session->distcode, CP_FLD_TERM, MXIT_CP_FEATURES, CP_FLD_TERM, + MXIT_CP_CAP, CP_FLD_TERM, session->distcode, CP_FLD_TERM, features, CP_FLD_TERM, session->dialcode, CP_FLD_TERM, locale, CP_FLD_TERM, CP_MAX_FILESIZE, CP_FLD_TERM, MXIT_CP_PROTO_VESION, CP_FLD_TERM, 0 ); @@ -1039,7 +1054,6 @@ * @param nr_usernames Number of users being invited * @param usernames The usernames of the users being invited */ - void mxit_send_groupchat_invite( struct MXitSession* session, const char* roomid, int nr_usernames, const char* usernames[] ) { char data[CP_MAX_PACKET]; @@ -1322,6 +1336,10 @@ if ( records[1]->fcount >= 9 ) session->uid = g_strdup( records[1]->fields[8]->data ); + /* extract VoIP server (from protocol 6.2) */ + if ( records[1]->fcount >= 11 ) + g_strlcpy( session->voip_server, records[1]->fields[10]->data, sizeof( session->voip_server ) ); + /* display the current splash-screen */ if ( splash_popup_enabled( session ) ) splash_display( session ); @@ -1567,13 +1585,13 @@ */ static void mxit_parse_cmd_presence( struct MXitSession* session, struct record** records, int rcount ) { - struct record* rec; int i; purple_debug_info( MXIT_PLUGIN_ID, "mxit_parse_cmd_presence (%i recs)\n", rcount ); for ( i = 0; i < rcount; i++ ) { - rec = records[i]; + struct record* rec = records[i]; + int flags = 0; if ( rec->fcount < 6 ) { purple_debug_error( MXIT_PLUGIN_ID, "BAD PRESENCE RECORD! %i fields\n", rec->fcount ); @@ -1582,12 +1600,15 @@ /* * The format of the record is: - * contactAddressN\1presenceN\1moodN\1customMoodN\1statusMsgN\1avatarIdN + * contactAddressN \1 presenceN \1 moodN \1 customMoodN \1 statusMsgN \1 avatarIdN [ \1 flagsN ] */ mxit_strip_domain( rec->fields[0]->data ); /* contactAddress */ + if ( rec->fcount >= 7 ) /* flags field is included */ + flags = atoi( rec->fields[6]->data ); + mxit_update_buddy_presence( session, rec->fields[0]->data, atoi( rec->fields[1]->data ), atoi( rec->fields[2]->data ), - rec->fields[3]->data, rec->fields[4]->data ); + rec->fields[3]->data, rec->fields[4]->data, flags ); mxit_update_buddy_avatar( session, rec->fields[0]->data, rec->fields[5]->data ); } } diff -r 607ad979a753 -r b8d9329dda4a libpurple/protocols/mxit/protocol.h --- a/libpurple/protocols/mxit/protocol.h Fri Jan 07 19:56:19 2011 +0000 +++ b/libpurple/protocols/mxit/protocol.h Fri Jan 07 21:51:05 2011 +0000 @@ -75,6 +75,8 @@ #define MXIT_CF_NO_AVATARS 0x200000 #define MXIT_CF_GAMING 0x400000 #define MXIT_CF_GAMING_UPDATE 0x800000 +#define MXIT_CF_VOICE 0x1000000 +#define MXIT_CF_VIDEO 0x2000000 /* Client features supported by this implementation */ #define MXIT_CP_FEATURES ( MXIT_CF_FILE_TRANSFER | MXIT_CF_FILE_ACCESS | MXIT_CF_AUDIO | MXIT_CF_MARKUP | MXIT_CF_EXT_MARKUP | MXIT_CF_NO_GATEWAYS | MXIT_CF_IMAGES | MXIT_CF_COMMANDS | MXIT_CF_VIBES | MXIT_CF_MIDP2 ) diff -r 607ad979a753 -r b8d9329dda4a libpurple/protocols/mxit/roster.c --- a/libpurple/protocols/mxit/roster.c Fri Jan 07 19:56:19 2011 +0000 +++ b/libpurple/protocols/mxit/roster.c Fri Jan 07 21:51:05 2011 +0000 @@ -443,8 +443,9 @@ * @param mood The new mood for the contact * @param customMood The custom mood identifier * @param statusMsg This is the contact's status message + * @param flags The contact's presence flags. */ -void mxit_update_buddy_presence( struct MXitSession* session, const char* username, short presence, short mood, const char* customMood, const char* statusMsg ) +void mxit_update_buddy_presence( struct MXitSession* session, const char* username, short presence, short mood, const char* customMood, const char* statusMsg, int flags ) { PurpleBuddy* buddy = NULL; struct contact* contact = NULL; @@ -470,6 +471,7 @@ contact->presence = presence; contact->mood = mood; + contact->capabilities = flags; /* validate mood */ if (( contact->mood < MXIT_MOOD_NONE ) || ( contact->mood > MXIT_MOOD_STRESSED )) diff -r 607ad979a753 -r b8d9329dda4a libpurple/protocols/mxit/roster.h --- a/libpurple/protocols/mxit/roster.h Fri Jan 07 19:56:19 2011 +0000 +++ b/libpurple/protocols/mxit/roster.h Fri Jan 07 21:51:05 2011 +0000 @@ -79,6 +79,11 @@ #define MXIT_CFLAG_FOCUS_SEND_BLANK 0x20000 +/* MXit presence flags */ +#define MXIT_PFLAG_VOICE 0x1 +#define MXIT_PFLAG_VIDEO 0x2 + + /* Subscription types */ #define MXIT_SUBTYPE_BOTH 'B' #define MXIT_SUBTYPE_PENDING 'P' @@ -108,6 +113,7 @@ short mood; /* contact current mood */ int flags; /* contact flags */ short presence; /* presence state */ + int capabilities; /* contact capabilities */ short subtype; /* subscription type */ char* msg; /* invite/rejection message */ @@ -129,7 +135,7 @@ /* MXit Protocol callbacks */ void mxit_update_contact( struct MXitSession* session, struct contact* contact ); -void mxit_update_buddy_presence( struct MXitSession* session, const char* username, short presence, short mood, const char* customMood, const char* statusMsg ); +void mxit_update_buddy_presence( struct MXitSession* session, const char* username, short presence, short mood, const char* customMood, const char* statusMsg, int flags ); void mxit_update_buddy_avatar( struct MXitSession* session, const char* username, const char* avatarId ); void mxit_new_subscription( struct MXitSession* session, struct contact* contact ); void mxit_update_blist( struct MXitSession* session ); diff -r 607ad979a753 -r b8d9329dda4a libpurple/protocols/mxit/voicevideo.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libpurple/protocols/mxit/voicevideo.c Fri Jan 07 21:51:05 2011 +0000 @@ -0,0 +1,154 @@ +/* + * MXit Protocol libPurple Plugin + * + * -- voice & video -- + * + * Andrew Victor + * + * (C) Copyright 2010 MXit Lifestyle (Pty) Ltd. + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA + */ + +#include "purple.h" +#include "mxit.h" +#include "roster.h" +#include "voicevideo.h" + +#if defined(USE_VV) && defined(MXIT_DEV_VV) + +#warning "MXit VV support enabled." + +/*------------------------------------------------------------------------ + * Does this client support Voice? + */ +gboolean mxit_audio_enabled(void) +{ + PurpleMediaManager *manager = purple_media_manager_get(); + PurpleMediaCaps caps = purple_media_manager_get_ui_caps(manager); + + return (caps & PURPLE_MEDIA_CAPS_AUDIO); +} + +/*------------------------------------------------------------------------ + * Does this client support Voice and Video? + */ +gboolean mxit_video_enabled(void) +{ + PurpleMediaManager *manager = purple_media_manager_get(); + PurpleMediaCaps caps = purple_media_manager_get_ui_caps(manager); + + return (caps & PURPLE_MEDIA_CAPS_VIDEO); +} + +/*------------------------------------------------------------------------ + * Return the list of media capabilities this contact supports. + * + * @param account The MXit account object + * @param who The username of the contact. + * @return The media capabilities supported + */ +PurpleMediaCaps mxit_media_caps(PurpleAccount *account, const char *who) +{ + struct MXitSession* session = purple_account_get_connection(account)->proto_data; + PurpleBuddy* buddy; + struct contact* contact; + PurpleMediaCaps capa = PURPLE_MEDIA_CAPS_NONE; + + purple_debug_info(MXIT_PLUGIN_ID, "mxit_media_caps: buddy '%s'\n", who); + + /* We need to have a voice/video server */ + if (strlen(session->voip_server) == 0) + return PURPLE_MEDIA_CAPS_NONE; + + /* find the buddy information for this contact (reference: "libpurple/blist.h") */ + buddy = purple_find_buddy(account, who); + if (!buddy) { + purple_debug_warning(MXIT_PLUGIN_ID, "mxit_media_caps: unable to find the buddy '%s'\n", who); + return PURPLE_MEDIA_CAPS_NONE; + } + + contact = purple_buddy_get_protocol_data(buddy); + if (!contact) + return PURPLE_MEDIA_CAPS_NONE; + + /* can only communicate with MXit users */ + if (contact->type != MXIT_TYPE_MXIT) + return PURPLE_MEDIA_CAPS_NONE; + + /* and only with contacts in the 'Both' subscription state */ + if (contact->subtype != MXIT_SUBTYPE_BOTH) + return PURPLE_MEDIA_CAPS_NONE; + + /* and only when they're online */ + if (contact->presence == MXIT_PRESENCE_OFFLINE) + return MXIT_PRESENCE_OFFLINE; + + /* they support voice-only */ + if (contact->capabilities & MXIT_PFLAG_VOICE) + capa |= PURPLE_MEDIA_CAPS_AUDIO; + + /* they support voice-and-video */ + if (contact->capabilities & MXIT_PFLAG_VIDEO) + capa |= (PURPLE_MEDIA_CAPS_AUDIO | PURPLE_MEDIA_CAPS_VIDEO | PURPLE_MEDIA_CAPS_AUDIO_VIDEO); + + return capa; +} + + +/*------------------------------------------------------------------------ + * Initiate a voice/video session with a contact. + * + * @param account The MXit account object + * @param who The username of the contact. + * @param type The type of media session to initiate + * @return TRUE if session was initiated + */ +gboolean mxit_media_initiate(PurpleAccount *account, const char *who, PurpleMediaSessionType type) +{ + purple_debug_info(MXIT_PLUGIN_ID, "mxit_media_initiate: buddy '%s'\n", who); + + return FALSE; +} + +#else + +/* + * Voice and Video not supported. + */ + +gboolean mxit_audio_enabled(void) +{ + return FALSE; +} + +gboolean mxit_video_enabled(void) +{ + return FALSE; +} + +PurpleMediaCaps mxit_media_caps(PurpleAccount *account, const char *who) +{ + return PURPLE_MEDIA_CAPS_NONE; +} + +gboolean mxit_media_initiate(PurpleAccount *account, const char *who, PurpleMediaSessionType type) +{ + return FALSE; +} + +#endif + diff -r 607ad979a753 -r b8d9329dda4a libpurple/protocols/mxit/voicevideo.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libpurple/protocols/mxit/voicevideo.h Fri Jan 07 21:51:05 2011 +0000 @@ -0,0 +1,41 @@ +/* + * MXit Protocol libPurple Plugin + * + * -- voice & video -- + * + * Andrew Victor + * + * (C) Copyright 2010 MXit Lifestyle (Pty) Ltd. + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA + */ + +#ifndef _MXIT_VOICEVICEO_H_ +#define _MXIT_VOICEVIDEO_H_ + +#include "media.h" + + +#undef MXIT_DEV_VV + + +gboolean mxit_audio_enabled(void); +gboolean mxit_video_enabled(void); +PurpleMediaCaps mxit_media_caps(PurpleAccount* account, const char* who); +gboolean mxit_media_initiate(PurpleAccount* account, const char* who, PurpleMediaSessionType type); + + +#endif /* _MXIT_VOICEVIDEO_H_ */