Update to 0.5.4: Adding MUC room lookup and bug fixes.
git-svn-id: http://libjingle.googlecode.com/svn/trunk@61 dd674b97-3498-5ee5-1854-bdd07cd0ff33
diff --git a/CHANGELOG b/CHANGELOG
index 73ffc71..77c8795 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,5 +1,9 @@
Libjingle
+0.5.4 - May 13, 2011
+ - Support for MUC lookup by name
+ - Bug fixes
+
0.5.3 - May 10, 2011
- Stream notification and selection.
- Better XEP-0045 support.
diff --git a/talk/examples/call/callclient.cc b/talk/examples/call/callclient.cc
index 0dd58a9..895b58b 100644
--- a/talk/examples/call/callclient.cc
+++ b/talk/examples/call/callclient.cc
@@ -52,6 +52,7 @@
#include "talk/session/phone/mediasessionclient.h"
#include "talk/session/phone/videorendererfactory.h"
#include "talk/xmpp/constants.h"
+#include "talk/xmpp/mucroomlookuptask.h"
namespace {
@@ -115,7 +116,8 @@
" vcall [jid] [bw] Initiates a video call to the user[/room] with\n"
" the given JID and with optional bandwidth.\n"
" voicemail [jid] Leave a voicemail for the user with the given JID.\n"
-" join [room] Joins a multi-user-chat.\n"
+" join [room_jid] Joins a multi-user-chat with room JID.\n"
+" ljoin [room_name] Joins a MUC by looking up JID from room name.\n"
" invite user [room] Invites a friend to a multi-user-chat.\n"
" leave [room] Leaves a multi-user-chat.\n"
" getdevs Prints the available media devices.\n"
@@ -199,6 +201,8 @@
MakeCallTo(to, options);
} else if (command == "join") {
JoinMuc(GetWord(words, 1, ""));
+ } else if (command == "ljoin") {
+ LookupAndJoinMuc(GetWord(words, 1, ""));
} else if ((words.size() >= 2) && (command == "invite")) {
InviteToMuc(words[1], GetWord(words, 2, ""));
} else if (command == "leave") {
@@ -637,30 +641,46 @@
talk_base::Thread::Current()->Quit();
}
-void CallClient::JoinMuc(const std::string& room) {
- buzz::Jid room_jid;
- if (room.length() > 0) {
- room_jid = buzz::Jid(room);
- } else {
- // generate a GUID of the form XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX,
- // for an eventual JID of private-chat-<GUID>@groupchat.google.com
- char guid[37], guid_room[256];
- for (size_t i = 0; i < ARRAY_SIZE(guid) - 1;) {
- if (i == 8 || i == 13 || i == 18 || i == 23) {
- guid[i++] = '-';
- } else {
- sprintf(guid + i, "%04x", rand());
- i += 4;
- }
- }
-
- talk_base::sprintfn(guid_room, ARRAY_SIZE(guid_room),
- "private-chat-%s@%s", guid, pmuc_domain_.c_str());
- room_jid = buzz::Jid(guid_room);
+void CallClient::LookupAndJoinMuc(const std::string& room_name) {
+ // The room_name can't be empty for lookup task.
+ if (room_name.empty()) {
+ console_->Print("Please provide a room name or room jid.");
+ return;
}
+ std::string room = room_name;
+ std::string domain = xmpp_client_->jid().domain();
+ if (room_name.find("@") != std::string::npos) {
+ // Assume the room_name is a fully qualified room name.
+ // We'll find the room name string and domain name string from it.
+ room = room_name.substr(0, room_name.find("@") - 1);
+ domain = room_name.substr(room_name.find("@") + 1);
+ }
+
+ buzz::MucRoomLookupTask* lookup_query_task =
+ new buzz::MucRoomLookupTask(xmpp_client_, room, domain);
+ lookup_query_task->SignalRoomLookupResponse.connect(this,
+ &CallClient::OnRoomLookupResponse);
+ lookup_query_task->SignalRoomLookupError.connect(this,
+ &CallClient::OnRoomLookupError);
+ lookup_query_task->Start();
+}
+
+void CallClient::JoinMuc(const std::string& room_jid_str) {
+ if (room_jid_str.empty()) {
+ buzz::Jid room_jid = GenerateRandomMucJid();
+ console_->Printf("Generated a random room jid: %s",
+ room_jid.Str().c_str());
+ JoinMuc(room_jid);
+ } else {
+ JoinMuc(buzz::Jid(room_jid_str));
+ }
+}
+
+void CallClient::JoinMuc(const buzz::Jid& room_jid) {
if (!room_jid.IsValid()) {
- console_->Printf("Unable to make valid muc endpoint for %s", room.c_str());
+ console_->Printf("Unable to make valid muc endpoint for %s",
+ room_jid.Str().c_str());
return;
}
@@ -675,6 +695,15 @@
presence_out_->SendDirected(muc->local_jid(), my_status_);
}
+void CallClient::OnRoomLookupResponse(const buzz::MucRoomInfo& room_info) {
+ JoinMuc(room_info.room_jid);
+}
+
+void CallClient::OnRoomLookupError(const buzz::XmlElement* stanza) {
+ console_->Printf("%s\n", "Failed to look up the room_jid.",
+ stanza->Str().c_str());
+}
+
void CallClient::OnMucInviteReceived(const buzz::Jid& inviter,
const buzz::Jid& room,
const std::vector<buzz::AvailableMediaEntry>& avail) {
@@ -695,7 +724,7 @@
console_->Printf(" None\n");
}
// We automatically join the room.
- JoinMuc(room.Str());
+ JoinMuc(room);
}
void CallClient::OnMucJoined(const buzz::Jid& endpoint) {
@@ -903,3 +932,24 @@
}
call_->SendViewRequest(session, request);
}
+
+buzz::Jid CallClient::GenerateRandomMucJid() {
+ // Generate a GUID of the form XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX,
+ // for an eventual JID of private-chat-<GUID>@groupchat.google.com.
+ char guid[37], guid_room[256];
+ for (size_t i = 0; i < ARRAY_SIZE(guid) - 1;) {
+ if (i == 8 || i == 13 || i == 18 || i == 23) {
+ guid[i++] = '-';
+ } else {
+ sprintf(guid + i, "%04x", rand());
+ i += 4;
+ }
+ }
+
+ talk_base::sprintfn(guid_room,
+ ARRAY_SIZE(guid_room),
+ "private-chat-%s@%s",
+ guid,
+ pmuc_domain_.c_str());
+ return buzz::Jid(guid_room);
+}
diff --git a/talk/examples/call/callclient.h b/talk/examples/call/callclient.h
index 4c2da17..82fc472 100644
--- a/talk/examples/call/callclient.h
+++ b/talk/examples/call/callclient.h
@@ -49,8 +49,11 @@
class DiscoInfoQueryTask;
class Muc;
class Status;
+class MucRoomLookupTask;
class MucStatus;
+class XmlElement;
struct AvailableMediaEntry;
+struct MucRoomInfo;
}
namespace talk_base {
@@ -110,7 +113,9 @@
void SendChat(const std::string& to, const std::string msg);
void InviteFriend(const std::string& user);
- void JoinMuc(const std::string& room);
+ void JoinMuc(const buzz::Jid& room_jid);
+ void JoinMuc(const std::string& room_jid_str);
+ void LookupAndJoinMuc(const std::string& room_name);
void InviteToMuc(const std::string& user, const std::string& room);
void LeaveMuc(const std::string& room);
void SetPortAllocatorFlags(uint32 flags) { portallocator_flags_ = flags; }
@@ -160,6 +165,9 @@
void OnMediaSourcesUpdate(cricket::Call* call,
cricket::Session* session,
const cricket::MediaSources& sources);
+ void OnRoomLookupResponse(const buzz::MucRoomInfo& room_info);
+ void OnRoomLookupError(const buzz::XmlElement* stanza);
+ buzz::Jid GenerateRandomMucJid();
void AddStaticRenderedView(
cricket::Session* session,
diff --git a/talk/libjingle.scons b/talk/libjingle.scons
index cc7947c..1e47ab5 100644
--- a/talk/libjingle.scons
+++ b/talk/libjingle.scons
@@ -200,6 +200,7 @@
"xmllite/xmlprinter.cc",
"xmpp/constants.cc",
"xmpp/jid.cc",
+ "xmpp/mucroomlookuptask.cc",
"xmpp/ratelimitmanager.cc",
"xmpp/saslmechanism.cc",
"xmpp/xmppclient.cc",
diff --git a/talk/p2p/base/sessionmessages.cc b/talk/p2p/base/sessionmessages.cc
index d15c9e3..a0b1aa7 100644
--- a/talk/p2p/base/sessionmessages.cc
+++ b/talk/p2p/base/sessionmessages.cc
@@ -127,13 +127,7 @@
if (jingle == NULL)
return false;
- return (jingle->HasAttr(buzz::QN_ACTION) &&
- (jingle->HasAttr(QN_SID)
- // TODO: This works around a bug in old jingle
- // clients that set QN_ID instead of QN_SID. Once we know
- // there are no clients which have this bug, we can remove
- // this code.
- || jingle->HasAttr(QN_ID)));
+ return (jingle->HasAttr(buzz::QN_ACTION) && jingle->HasAttr(QN_SID));
}
bool IsGingleMessage(const buzz::XmlElement* stanza) {
@@ -176,12 +170,6 @@
std::string type_string = jingle->Attr(buzz::QN_ACTION);
msg->type = ToActionType(type_string);
msg->sid = jingle->Attr(QN_SID);
- // TODO: This works around a bug in old jingle clients
- // that set QN_ID instead of QN_SID. Once we know there are no
- // clients which have this bug, we can remove this code.
- if (msg->sid.empty()) {
- msg->sid = jingle->Attr(buzz::QN_ID);
- }
msg->initiator = GetXmlAttr(jingle, QN_INITIATOR, buzz::STR_EMPTY);
msg->action_elem = jingle;
@@ -235,15 +223,9 @@
buzz::XmlElement* jingle = new buzz::XmlElement(QN_JINGLE, true);
jingle->AddAttr(buzz::QN_ACTION, ToJingleString(msg.type));
jingle->AddAttr(QN_SID, msg.sid);
- // TODO: This works around a bug in old jingle clinets
- // that expected QN_ID instead of QN_SID. Once we know there are no
- // clients which have this bug, we can remove this code.
- jingle->AddAttr(QN_ID, msg.sid);
- // TODO: Right now, the XMPP server rejects a jingle-only
- // (non hybrid) message with "feature-not-implemented" if there is
- // no initiator. Fix the server, and then only set the initiator on
- // session-initiate messages here.
- jingle->AddAttr(QN_INITIATOR, msg.initiator);
+ if (msg.type == ACTION_SESSION_INITIATE) {
+ jingle->AddAttr(QN_INITIATOR, msg.initiator);
+ }
AddXmlChildren(jingle, action_elems);
return jingle;
}
diff --git a/talk/session/phone/call.cc b/talk/session/phone/call.cc
index a150688..64ebcef 100644
--- a/talk/session/phone/call.cc
+++ b/talk/session/phone/call.cc
@@ -548,8 +548,12 @@
// For backwards compatibility, we remove by nick.
// TODO: Remove once all senders use explicit remove by ssrc.
found = media_sources.GetFirstAudioSourceByNick(it->nick);
- it->SetSsrc(found->ssrc);
- it->removed = true;
+ if (found) {
+ it->SetSsrc(found->ssrc);
+ it->removed = true;
+ } else {
+ continue; // No ssrc to remove.
+ }
}
if (it->removed && found) {
LOG(LS_INFO) << "Remove voice stream: " << found->ssrc;
@@ -571,8 +575,12 @@
// For backwards compatibility, we remove by nick.
// TODO: Remove once all senders use explicit remove by ssrc.
found = media_sources.GetFirstVideoSourceByNick(it->nick);
- it->SetSsrc(found->ssrc);
- it->removed = true;
+ if (found) {
+ it->SetSsrc(found->ssrc);
+ it->removed = true;
+ } else {
+ continue; // No ssrc to remove.
+ }
}
if (it->removed && found) {
LOG(LS_INFO) << "Remove video stream: " << found->ssrc;
diff --git a/talk/xmpp/constants.cc b/talk/xmpp/constants.cc
index db9095f..b19c124 100644
--- a/talk/xmpp/constants.cc
+++ b/talk/xmpp/constants.cc
@@ -158,6 +158,7 @@
const std::string STR_UNAVAILABLE("unavailable");
+const std::string STR_MUC_LOOKUP_DOMAIN("lookup.groupchat.google.com");
const QName QN_STREAM_STREAM(true, NS_STREAM, STR_STREAM);
const QName QN_STREAM_FEATURES(true, NS_STREAM, "features");
@@ -395,6 +396,15 @@
const QName QN_MUC_USER_STATUS(true, NS_MUC_USER, "status");
+// JEP 0055 - Jabber Search
+const std::string NS_SEARCH("jabber:iq:search");
+const QName QN_SEARCH_QUERY(true, NS_SEARCH, "query");
+const QName QN_SEARCH_ITEM(true, NS_SEARCH, "item");
+const QName QN_SEARCH_ROOM_NAME(true, NS_SEARCH, "room-name");
+const QName QN_SEARCH_ORGANIZERS_DOMAIN(true, NS_SEARCH, "organizers-domain");
+const QName QN_SEARCH_ROOM_JID(true, NS_SEARCH, "room-jid");
+
+
// JEP 0115
const std::string NS_CAPS("http://jabber.org/protocol/caps");
const QName QN_CAPS_C(true, NS_CAPS, "c");
diff --git a/talk/xmpp/constants.h b/talk/xmpp/constants.h
index 8df83b9..dfd4178 100644
--- a/talk/xmpp/constants.h
+++ b/talk/xmpp/constants.h
@@ -112,6 +112,7 @@
extern const std::string STR_UNAVAILABLE;
+extern const std::string STR_MUC_LOOKUP_DOMAIN;
extern const QName QN_STREAM_STREAM;
extern const QName QN_STREAM_FEATURES;
@@ -361,6 +362,15 @@
extern const QName QN_MUC_USER_STATUS;
+// JEP 0055 - Jabber Search
+extern const std::string NS_SEARCH;
+extern const QName QN_SEARCH_QUERY;
+extern const QName QN_SEARCH_ITEM;
+extern const QName QN_SEARCH_ROOM_NAME;
+extern const QName QN_SEARCH_ROOM_JID;
+extern const QName QN_SEARCH_ORGANIZERS_DOMAIN;
+
+
// JEP 0115
extern const std::string NS_CAPS;
extern const QName QN_CAPS_C;